社区讨论

可能是编译器级别的 bug(也可能仅限 luogu)

学术版参与者 6已保存回复 19

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
18 条
当前快照
1 份
快照标识符
@mifddf1h
此快照首次捕获于
2025/11/26 10:12
3 个月前
此快照最后确认于
2025/11/26 12:50
3 个月前
查看原帖
事情是这样的。机房同学复习的时候写了笛卡尔树的板子,在 P5854 【模板】笛卡尔树 ,写下了如下代码:
CPP
#include<bits/stdc++.h>

using namespace std;
bool Mbe;

using i64=long long;

constexpr int maxn=1e7+10;

int n,a[maxn];

int tp,stk[maxn],ch[maxn][2];

i64 ans0,ans1;

bool Med;
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);

	cin>>n;
	for(int i=1;i<=n;++i) cin>>a[i];
	
	for(int i = 1; i <= n; ++i) {
    	int last = 0;
    	while(tp && a[i] < a[stk[tp]]) last = stk[tp--];
    	if(tp) ch[stk[tp]][1] = i;
    	if(last) ch[i][0] = last;
    	stk[++tp] = i;
    }

	
	for(int i=1;i<=n;++i) ans0^=(i64)i*(ch[i][0]+1),ans1^=(i64)i*(ch[i][1]+1);//
	
	cout<<ans0<<' '<<ans1<<'\n';
	
	// cerr<<'\n'<<fabs(&Med-&Mbe)/1048576.0<<"MB\n";
	// cerr<<'\n'<<1e3*clock()/CLOCKS_PER_SEC<<"ms\n";
	return 0;
}
然后他发现过不去,感到非常困惑。然后他改用 C++14(GCC 9) 发现直接过了。然后经过测试,在 luoguIDE 上面除了 GCC 9 以外所有的都通过不了给出的小样例。
根据某大模型给出的意思是 O2 优化的问题,于是我们将 O2 优化关了确实就对的。
然后根据直觉,我们将括号内的符号强转成 long long
CPP
for(int i=1;i<=n;++i) ans0^=(i64)i*((i64)ch[i][0]+1),ans1^=(i64)i*((i64)ch[i][1]+1);//
然后就过了。
我们认为这个问题非常奇怪,因为这个含义很正常,应该不存在歧义,同时 ^= 号也比较常用。如果这都能错感觉不太好识别。于是去其他编译器上测试。
但是奇怪的地方是,在本地,我们校内的 OJ,CF Custom test 所有版本的 C++ 全都是对的。所以我们认为可能是 luogu 自己编译器的问题,但是我们找不到证据。
同时我比较菜,也不太懂编译器方面的知识。所以有大佬可以解决一下疑惑吗?

回复

19 条回复,欢迎继续交流。

正在加载回复...