当前位置: 首页 > news >正文

CSP-S2025 游记:没人告诉我 NOI Linux 有编译器 bug 啊?

初赛 100,复赛 400......390????

replace 挂了 \(10\) 分,为什么呢??

好的,拿到代码了,赶紧交一下......所有民间数据都通过了啊?

官方数据出了,赶紧交一下......怎么官方数据也过了?难道被卡常了?明明时间复杂度是正确的 \(O((n+q)\log L+L)\) 啊。

放到 NOI Linux 上面跑一下......replace13 怎么爆空间了?实际空间 3G??赛时测过静态空间才 1G,动态空间也只有 eps,并且各 OJ 都正常通过啊?

完整代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define gc() getchar()
#define putc(c) putchar(c)
inline int read(){int x=0,t=0;char c=gc();while(c<'0'||c>'9') t|=c=='-',c=gc();while(c>='0'&&c<='9') x=x*10+c-'0',c=gc();return t?-x:x;
}
inline void write(int x){if(x<0) putc('-'),x=-x;if(x>9) write(x/10);putc(x%10+'0');
}
inline int readstr(char *s){int l=0;char c=gc();while(c<'a'||c>'z') c=gc();while(c>='a'&&c<='z') s[++l]=c,c=gc();s[l+1]=0;return l;
}
#define mpr make_pair
#define pii pair<int,int>
#define fir first
#define sec second
//bool st;
using node=array<int,3>;
const int N=2e5+10,L=5e6+10;
const int bas=131,m1=998244853,m2=1e9+9;
int n,q,cd,ans[N],ls[N],lt[N],rs[N],rt[N],p;
char s[L],t[L],sp[L];
int son[L][26],cnt;
pii hsh[N];
vector<node>qr[L],md[L];
map<pii,int>id;
int dfn[L],low[L],tim;
inline void dfs0(int x){dfn[x]=++tim;for(int c=0;c<26;c++)if(son[x][c])dfs0(son[x][c]);low[x]=tim;
}
struct Segment_Tree{#define ls (a[rt].lson)#define rs (a[rt].rson)struct node{int lson,rson,tag;}a[N*60];int cnt;inline void add(int &rt,int l,int r,int L,int R,int v){if(!rt) rt=++cnt;if(L<=l&&r<=R){ a[rt].tag+=v;return ; }int mid=l+r>>1;if(L<=mid) add(ls,l,mid,L,R,v);if(R>mid) add(rs,mid+1,r,L,R,v);}inline int query(int rt,int l,int r,int p){if(!rt) return 0;if(l==r) return a[rt].tag;int mid=l+r>>1;if(p<=mid) return query(ls,l,mid,p)+a[rt].tag;else return query(rs,mid+1,r,p)+a[rt].tag;}#undef ls#undef rs
}T;
int rtp[N];
inline void dfs1(int x){for(auto tp:md[x]){int p=tp[1],id=tp[2];T.add(rtp[id],1,tim,dfn[p],low[p],1);}for(auto tp:qr[x]){int p=tp[1],id=tp[2];ans[tp[0]]=T.query(rtp[id],1,tim,dfn[p]);}for(int c=0;c<26;c++)if(son[x][c])dfs1(son[x][c]);for(auto tp:md[x]){int p=tp[1],id=tp[2];T.add(rtp[id],1,tim,dfn[p],low[p],-1);}
}
//bool ed;
int main(){
//	printf("%.2lfMB\n",(&st-&ed)/1024./1024.);
//	system("fc replace1.out replace1.ans /n");
//	system("fc replace2.out replace2.ans /n");
//	system("fc replace3.out replace3.ans /n");
//	system("fc replace4.out replace4.ans /n");freopen("replace.in","r",stdin);freopen("replace.out","w",stdout);n=read(),q=read();for(int i=1;i<=n;i++){int l=readstr(s),lp=readstr(t);assert(l==lp);bool fl=0;for(int j=1;j<=l;j++)fl|=s[j]!=t[j];if(!fl) continue;int lx=0,rx=0;for(int j=1;j<=l;j++)if(s[j]!=t[j])lx=(lx?lx:j),rx=j;ls[i]=p+1;for(int j=lx-1;j;j--)sp[++p]=s[j];lt[i]=p,rs[i]=p+1;for(int j=rx+1;j<=l;j++)sp[++p]=s[j];rt[i]=p;int hs1=0,hs2=0;for(int j=lx;j<=rx;j++)hs1=(1ll*hs1*bas+s[j])%m1,hs2=(1ll*hs2*bas+s[j])%m2,hs1=(1ll*hs1*bas+t[j])%m1,hs2=(1ll*hs2*bas+t[j])%m2;hsh[i]=mpr(hs1,hs2); }for(int i=1;i<=q;i++){int l=readstr(s),lp=readstr(t);if(l!=lp) continue;int lx=0,rx=0;for(int j=1;j<=l;j++)if(s[j]!=t[j])lx=(lx?lx:j),rx=j;int hs1=0,hs2=0;for(int j=lx;j<=rx;j++)hs1=(1ll*hs1*bas+s[j])%m1,hs2=(1ll*hs2*bas+s[j])%m2,hs1=(1ll*hs1*bas+t[j])%m1,hs2=(1ll*hs2*bas+t[j])%m2;pii tp=mpr(hs1,hs2);if(!id.count(tp)) id[tp]=++cd;int pl=0,pr=0;for(int j=lx-1;j>=1;j--){int c=s[j]-'a';if(!son[pl][c]) son[pl][c]=++cnt;pl=son[pl][c];}for(int j=rx+1;j<=l;j++){int c=s[j]-'a';if(!son[pr][c]) son[pr][c]=++cnt;pr=son[pr][c];}qr[pl].push_back((node){i,pr,id[tp]});}for(int i=1;i<=n;i++){if(!ls[i]||!id.count(hsh[i])) continue;int pl=0,pr=0;for(int j=ls[i];j<=lt[i];j++){int c=sp[j]-'a';if(!son[pl][c]){ pl=-1;break; }pl=son[pl][c];}for(int j=rs[i];j<=rt[i];j++){int c=sp[j]-'a';if(!son[pr][c]){ pr=-1;break; }pr=son[pr][c];}if(pl==-1||pr==-1) continue;md[pl].push_back((node){i,pr,id[hsh[i]]});}dfs0(0),dfs1(0);
//	cerr<<cnt<<" "<<T.cnt<<endl;for(int i=1;i<=q;i++)write(ans[i]),putc('\n');
}

怎么问题定位到线段树了??

关闭 O2、使用高版本 gcc、给 query 函数加 __attribute__((noinline)),或者在里面定义任何临时变量都会让空间正常地变成 1G

再怎么说 O2 也不会把我的空间翻三倍吧......

问 AI 的回答是:

LA 群友的验证:

经检测是算入了栈空间,猜测编译器发现 query 函数递归层数只有 \(20\) 层,就自动展开了,往栈里面放了一堆 int

开启 --param max-inline-recursive-depth=2 编译选项也不会 MLE。

经检测,确实如此。

警钟长鸣,但是不知道要鸣什么。可能是不要让自己代码太好看,给 -O2 优化掉吧。或者说加点东西让编译器不要给你内联。

CCF 用个老旧版本 gcc,考场又没有对应版本,根本无法查错。再怎样也不该用 2G 的空间给我做优化啊,老版本的 gcc bug......

本身就是考着玩,顺便看看能不能拿到 OI 生涯第一个 400 的。反正官方数据正常通过了,我认为自己拿了 400 不过分吧。

如果对这个问题有别的想法欢迎评论回复。

http://icebutterfly214.com/news/21771/

相关文章:

  • 2025年口碑好的自上料搅拌车厂家最新热销排行
  • 2025 年方涵源头厂家最新推荐榜单:发掘供应稳定实力企业,涵盖水泥、混凝土、预制等各类方涵优质品牌
  • 2025年靠谱的商用爬杆挂面机厂家最新TOP实力排行
  • vscode关闭copilot:版本1.105.1
  • 【课程设计/毕业设计】Java家政预约管理系统源码+开发文档+运行步骤
  • 2025年11月三角梅批发基地排行:五家园区参数全面对比
  • 2025年上海血管瘤医院联系电话推荐:微创激光全程指引
  • LiveLessons - Introduction to the FreeBSD Open-Source Operating System
  • 2025年靠谱的B1级橡塑保温板行业内知名厂家排行榜
  • C#/.NET/.NET Core优秀项目和框架2025年10月简报
  • AI元人文:三值显隐机制与共识公正性保障体系
  • 2025 年 11 月冷库板/聚氨酯冷库板/机制板, 冷库门, 冷库工程/冷库集成厂家推荐排行榜:专业制造与高效保温系统解决方案
  • 价值权衡的完整计算模型:价值体系与规则体系的辩证统一
  • 2025年11月黄黑皮美白产品对比榜:从成分到肤感十款实测排名
  • 2025年11月学生平板品牌推荐:护眼大屏榜对比学习场景差异
  • 2025年11月适合小学生的学习机推荐榜:五强参数与体验全解析
  • 每日反思(2025_11_05)
  • CRT弹窗接收用户文本输入
  • 题解:AT_abc225_h [ABC225H] Social Distance 2
  • 表相关操作
  • 102302149赖翊煊数据采集第二次作业
  • 引领未来,智启新程:Compete MIS平台——低代码时代的全能信息化管理解决方案
  • CF2085D Serval and Kaitenzushi Buffet
  • 11月6日
  • Spring ApplicationEventPublisher 事件发布
  • 选择 Tita 新绩效一体化的 5 大理由
  • 团队第一次作业
  • 备考笔记8
  • 数字识别模型
  • 搜维尔科技:Xsens动作捕捉系统实时捕捉人体运动数据,为人形机器人提供拟人化动作训练和实时控制支持