关于 GDOI2025 GD-004 D2T1 的编译错误代码

/day2-GD-Senior-加密/answers/GD-004/move/move.cpp
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int getchar(){
	static char a[1<<20],*p=a,*q=a;
	if(p==q) q=(p=a)+fread(a,1,1<<20,stdin);
	return *p++;
}
inline int read(){
	int x=0; int c=getchar();
	for(;c<'0'||c>'9';c=getchar());
	for(;c>='0'&&c<='9';c=getchar()) x=(x*10)+(c^48);
	return x;
}
inline ll readll(){
	ll x=0; int c=getchar();
	for(;c<'0'||c>'9';c=getchar());
	for(;c>='0'&&c<='9';c=getchar()) x=(x*10)+(c^48);
	return x;
}
const int N=2e5+10;
ll arith(int l,int r){ return (r-l+1ll)*(l+r)>>1; }
int n;
int a[N],b[N]; ll tim[N];
int ord[N];
struct segt{
	static const int M=N<<2;
	int lef[M],rit[M],tag[M];
	ll sum[M];
	void psu(int p){
		lef[p]=lef[p<<1];
		rit[p]=rit[p<<1|1];
		sum[p]=sum[p<<1]+sum[p<<1|1];
//		printf("%d: lef %d rit %d sum %lld\n",p,lef[p],rit[p],sum[p]);
	}
	void psd(int p){
		if(!tag[p]) return;
		int mid=(lef[p]+rit[p])>>1;
		lef[p<<1]=lef[p];
		rit[p<<1]=mid;
		sum[p<<1]=arith(lef[p],mid);
		lef[p<<1|1]=mid+1;
		rit[p<<1|1]=rit[p];
		sum[p<<1|1]=arith(mid+1,rit[p]);
		tag[p<<1]=tag[p<<1|1]=true;
		tag[p]=false;
	}
	void build(int l,int r,int p){
		tag[p]=0;
		if(l==r) {
			lef[p]=rit[p]=sum[p]=a[l];
			return;
		}
		int mid=(l+r)>>1;
		build(l,mid,p<<1);
		build(mid+1,r,p<<1|1);
		psu(p);
	}
	void push_left(int l,int r,int p,int x,int d){
		if(r==x&&d-(r-l)<=lef[p]){
			tag[p]=true;
			rit[p]=d;
			lef[p]=d-(r-l);
			sum[p]=arith(lef[p],rit[p]);
			return;
		}
		assert(l!=r);
		psd(p);
		int mid=(l+r)>>1;
		if(x<=mid) push_left(l,mid,p<<1,x,d);
		else{
			push_left(mid+1,r,p<<1|1,x,d);
			int plc=lef[p<<1|1]-1;
			if(plc<rit[p<<1]) push_left(l,mid,p<<1,mid,plc);
		}
		psu(p);
	}
	void push_right(int l,int r,int p,int x,int d){
//		printf("right %d %d %d %d %d\n",l,r,p,x,d);
		if(l==x&&d+(r-l)>=rit[p]){
			tag[p]=true;
			lef[p]=d;
			rit[p]=d+(r-l);
			sum[p]=arith(lef[p],rit[p]);
			return;
		}
		assert(l!=r);
		psd(p);
		int mid=(l+r)>>1;
		if(x>mid) push_right(mid+1,r,p<<1|1,x,d);
		else{
			push_right(l,mid,p<<1,x,d);
			int plc=rit[p<<1]+1;
			if(plc>lef[p<<1|1]) push_right(mid+1,r,p<<1|1,mid+1,plc);
		}
		psu(p);
	}
	void build(){ build(1,n,1); }
//	void dfs(int l,int r,int p){
//		if(l==r){
//			assert(lef[p]==rit[p]);
//			printf("%d ",lef[p]);
//			return ;
//		}
//		int mid=(l+r)>>1;
//		psd(p);
//		dfs(l,mid,p<<1); dfs(mid+1,r,p<<1|1);
//	}
//	void debug(){
//		for(int i=1;i<=5;i++){
//			printf("%d: lef %d rit %d sum %lld\n",i,lef[i],rit[i],sum[i]);
//		}
//		dfs(1,n,1);
//		puts("");
//	}
	ll push_left(int x,int d){
		ll before=sum[1];
		push_left(1,n,1,x,d);
		ll after=sum[1];
//		printf("move LEF %d to %d cost %lld\n",x,d,before-after);
//		debug();
		return before-after;
	}
	ll push_right(int x,int d){
		ll before=sum[1];
		push_right(1,n,1,x,d);
		ll after=sum[1];
//		printf("move RIT %d to %d cost %lld\n",x,d,after-before);
//		debug();
		return after-before;
	}
}T;
void solve(){
	n=read();
	for(int i=1;i<=n;i++){
		a[i]=read(); b[i]=read(); tim[i]=readll();
		ord[i]=i;
	}
	sort(ord+1,ord+n+1,[&](int x,int y){ return tim[x]<tim[y]; });
	T.build();
	ll rem=0;
	for(int j=1;j<=n;j++){
		int i=ord[j];
		rem+=tim[i]-tim[ord[j-1]];
		if(b[i]<a[i]) rem-=T.push_left(i,b[i]);
		else rem-=T.push_right(i,b[i]);
		if(rem<0){
			puts("No");
			return;
		}
	}
	puts("Yes");
}
int main(){
	freopen("move.in","r",stdin);
	freopen("move.out","w",stdout);
	int tc; read(); tc=read();
	while(tc--){
//		auto st=clock();
		solve();
//		auto ed=clock();
//		cerr<<"CASE Time: "<<ed-st<<"\n";
	}
}

这份代码在 g++-9 -std=c++14 -O2 的编译选项下会编译错误

move.cpp:4:12: error: ‘int getchar()’ redeclared inline without ‘gnu_inline’ attribute
    4 | inline int getchar(){
      |            ^~~~~~~
In file included from /usr/include/stdio.h:976,
                 from /usr/include/c++/9/cstdio:42,
                 from /usr/include/x86_64-linux-gnu/c++/9/bits/stdc++.h:46,
                 from move.cpp:1:
/usr/include/x86_64-linux-gnu/bits/stdio.h:47:1: note: ‘int getchar()’ previously defined here
   47 | getchar (void)
      | ^~~~~~~
move.cpp: In function ‘int main()’:
move.cpp:155:9: warning: ignoring return value of ‘FILE* freopen(const char*, const char*, FILE*)’, declared with attribute warn_unused_result [-Wunused-result]
  155 |  freopen("move.in","r",stdin);
      |  ~~~~~~~^~~~~~~~~~~~~~~~~~~~~
move.cpp:156:9: warning: ignoring return value of ‘FILE* freopen(const char*, const char*, FILE*)’, declared with attribute warn_unused_result [-Wunused-result]
  156 |  freopen("move.out","w",stdout);
      |  ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~

这位选手定义了与标准库一样的函数名(inline int getchar()),本身是未定义行为,但更为致命的错误是 inline。去掉 inline 后可以编译通过,说明 inline 是问题所在。询问 AI 得到以下回答:

这个编译错误的原因主要是因为你重新定义了getchar函数并且使用了inline关键字,这与标准库中的getchar函数产生了冲突。以下是详细解释:

1. getchar函数的重定义问题

  • 标准库中的getchar函数getchar是C标准库中的一个函数,用于从标准输入读取一个字符。它在<stdio.h>头文件中已经被定义。
  • 你的代码中的getchar函数:你在代码中重新定义了getchar函数,并且使用了inline关键字。在C++中,当你使用inline关键字重新定义一个已经在标准库中存在的函数时,编译器会报错,因为这会导致符号冲突。

2. inline关键字的问题

  • inline关键字的作用inline关键字用于建议编译器将函数的调用替换为函数体,以减少函数调用的开销。但是,对于标准库中已经存在的函数,使用inline重新定义会导致冲突。
  • 解决方法:去掉inline关键字,或者使用gnu_inline属性(这是GCC特有的属性)。不过,为了避免与标准库函数冲突,最好的方法是重命名你自己定义的函数,不要使用与标准库函数相同的名称。
posted @ 2025-03-13 21:57  caijianhong  阅读(135)  评论(0)    收藏  举报