MnZn 求调 5pts WA

P5065 [Ynoi2014] 不归之人与望眼欲穿的人们

Magus @ 2025-01-10 20:10:31

PS:样例过了

所以目测是外层 query 炸了,但是没找到错误。 ``` // Problem:P5065 [Ynoi2014] 不归之人与望眼欲穿的人们 // Contest:Luogu // URL:https://www.luogu.com.cn/problem/P5065 // Memory Limit:125 MB // Time Limit:1000 ms // Luogu Account:qhzx_FeS2_Butterfly // Codeforces Account:Butterfly_qwq // Atcoder Account:Super_agg // CP Duel Rating:2007 // Start Coding:01-10 15:53 // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; const int N=50004,B=224; int n,m,blk[N],pos[N]; struct qu { int sz,dat[35]; inline int& operator [](const int& x){return dat[x];} }ans[230]; void insert(qu u,int w,qu& t,int pos) { t.sz=0; for(int i=0;i<31;i++)if(w&(1<<i))t[++t.sz]=(pos<<5)|i; for(int i=1;i<=u.sz;i++)if((~w)&(1<<(u[i]&31)))t[++t.sz]=u[i]; } void merge(qu u,qu v,int w,qu& t) { t.sz=0; for(int i=1;i<=u.sz;i++)if(w&(1<<(u[i]&31)))t[++t.sz]=u[i]; for(int i=1;i<=v.sz;i++)if((~w)&(1<<(v[i]&31)))t[++t.sz]=v[i]; } struct block { int sz,val,lst,a[230],mx[230];qu pre[230],suf[230]; inline int& operator [](const int& x){return a[x];} void getmax() { memset(mx,0xc0,sizeof(mx)); for(int i=1;i<=sz;i++)for(int j=1,r=0,u;j<=pre[i].sz;j++) { r|=(1<<(pre[i][j]&31)); u=i-(pre[i][j]>>5)+lst+1; mx[u]=max(mx[u],r); } for(int i=1;i<=sz;i++)mx[i]=max(mx[i],mx[i-1]); } void build() { for(int i=1;i<=sz;i++)val|=a[i]; for(int i=1;i<=sz;i++)insert(pre[i-1],a[i],pre[i],lst+i); for(int i=sz;i;i--)insert(suf[i+1],a[i],suf[i],lst+i); getmax(); } void update(int u,int w) { int inc=a[u]^w,r=0;a[u]=w;val=0; for(int i=1;i<=sz;i++)val|=a[i]; insert(pre[u-1],a[u],pre[u],lst+u); for(int i=u+1;i<=sz;i++) { insert(pre[i-1],a[i],pre[i],lst+i); r|=a[i];if(r==(r|inc))break; } getmax();r=0; insert(suf[u+1],a[u],suf[u],lst+u); for(int i=u-1;i;i--) { insert(suf[i+1],a[i],suf[i],lst+i); r|=a[i];if(r==(r|inc))break; } } int query(int k,int R) { int l=1,r=min(sz+1,R),mid; while(l<r) { mid=l+r>>1; if(mx[mid]>=k)r=mid; else l=mid+1; } if(l==sz+1)return 0x3f3f3f3f; return l; } }bl[230]; void init() { for(int i=1;i<=n;i++){blk[i]=(i-1)/B+1;pos[i]=(i-1)%B+1;} for(int i=1;i<blk[n];i++)bl[i].sz=B;bl[blk[n]].sz=pos[n]; for(int i=n;i;i--)bl[blk[i]].lst=i-1; } void update(int u,int w) { bl[blk[u]].update(pos[u],w); for(int i=blk[u];i;i--)merge(bl[i].suf[1],ans[i+1],bl[i].val,ans[i]); } int query(int k) { int res=0x3f3f3f3f;qu q; for(int i=1;i<=blk[n];i++)res=min(res,bl[i].query(k,res)); for(int i=blk[n],w,tmp;i>=2;i--) { w=bl[i-1].val;q=bl[i-1].pre[bl[i-1].sz]; for(int j=1,k=q.sz,r=0;j<=ans[i].sz;j++) { if((ans[i][j]>>5)-bl[i].lst>=res)break; r|=(1<<(ans[i][j]&31));if((r|w)<k)continue; while(k!=1) { tmp=w&(~(1<<(q[k]&31))); if((r|tmp)<k)break;k--;w=tmp; } res=min(res,(ans[i][j]>>5)-(q[k]>>5)+1); if(k==1)break; } } if(res==0x3f3f3f3f)return -1; return res; } int main() { cin>>n>>m;init(); for(int i=1;i<=n;i++)cin>>bl[blk[i]][pos[i]]; for(int i=1;i<=blk[n];i++)bl[i].build(); for(int i=blk[n];i;i--)merge(bl[i].suf[1],ans[i+1],bl[i].val,ans[i]); for(int i=1,op,k,x;i<=m;i++) { cin>>op>>k; if(op==1){cin>>x;update(k,x);} else cout<<query(k)<<'\n'; } } ```

by Magus @ 2025-01-10 22:21:53

过了,query 里面两个 k 重名了。

希望大家引以为戒,不要像 lz 一样犯这么傻逼的错误。


|