社区讨论
可能是编译器级别的 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 优化关了确实就对的。
然后根据直觉,我们将括号内的符号强转成
CPPlong long 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 条回复,欢迎继续交流。
正在加载回复...