LibreOJ β Round #2 F. 数学上来先打表
做法与题解基本无异,不过他说用vector我觉得用链表来得更好一些。
#include<queue> #include<ctime> #include<bitset> #include<vector> #include<cstdio> #include<algorithm> #define MN 110000 using namespace std; int read_p,read_ca,read_f; inline int read(){ read_p=0;read_ca=getchar();read_f=1; while(read_ca<'0'||read_ca>'9') {if (read_ca=='-') read_f=-1;read_ca=getchar();} while(read_ca>='0'&&read_ca<='9') read_p=read_p*10+read_ca-48,read_ca=getchar(); return read_p*read_f; } struct na{unsigned long long x;int p,ne;}b[MN*5]; int n,m,a[MN],id[MN],Ra[MN],now=0,pos[MN],T,num=0,qn=0,mmh[MN],sz[MN],fa[MN],l[MN],NUM=0,U[1<<16],SS=0; vector <int> Qx[MN],Qy[MN],Qp[MN],to[MN],x[MN],y[MN]; bool cmp(int x,int y){return a[x]<a[y];} inline int gf(int x){while(x!=fa[x]) x=fa[x];return x;} queue<int> q; inline void add(int x,int y){ if (x==y) return; fa[x]=y;sz[y]+=sz[x]; for (int A=l[x],*B=&l[y];A!=-1;A=b[A].ne){ while (b[*B].p<b[A].p&&*B!=-1) B=&b[*B].ne; if (*B==-1||b[*B].p>b[A].p){ int p;if(q.empty())p=NUM++;else p=q.front(),q.pop(); b[p].x=b[A].x;b[p].p=b[A].p; b[p].ne=*B;*B=p;B=&b[p].ne; }else b[*B].x^=b[A].x; } } inline void del(int x,int y){ if (x==y) return; fa[x]=x;sz[y]-=sz[x]; for (int A=l[x],*B=&l[y];A!=-1;A=b[A].ne){ while (b[*B].p<b[A].p&&*B!=-1) B=&b[*B].ne; b[*B].x^=b[A].x; if (!b[*B].x) q.push(*B),*B=b[*B].ne; } } inline int calc(int x,int y){ x=gf(x); if (sz[x]<y) return -1; for (int i=l[x];i!=-1;i=b[i].ne) if (y>U[b[i].x>>48]+U[(b[i].x>>32)&65535]+U[(b[i].x>>16)&65535]+U[b[i].x&65535]) y-=U[b[i].x>>48]+U[(b[i].x>>32)&65535]+U[(b[i].x>>16)&65535]+U[b[i].x&65535];else for (int j=0;j<64;j++) if ((b[i].x>>j)&1) if (!(--y)) return (b[i].p<<6)|j; } void dfs(int p){ for (int i=0;i<Qx[p].size();i++) mmh[Qp[p][i]]=calc(Qx[p][i],Qy[p][i]); for (int i=0;i<to[p].size();i++){ int X=x[p][i],Y=y[p][i]; if (X==-1) X=Y; X=gf(X);Y=gf(Y); if (sz[X]>sz[Y]) swap(X,Y); add(X,Y); dfs(to[p][i]); del(X,Y); } } int main(){ //freopen("a.in","r",stdin); n=read();m=read(); for (int i=1;i<(1<<16);i++) U[i]=U[i^(-i&i)]+1; for (int i=0;i<n;i++) a[i]=read(),id[i]=i,fa[i]=i,sz[i]=1; sort(id,id+n,cmp); for (int i=0;i<n;i++) l[id[i]]=i,b[i].x=1ull<<(i&63),b[i].p=i>>6,b[i].ne=-1;NUM=n; for (int i=1;i<=m;i++){ T=read(); if (T==1) num++,to[now].push_back(num),x[now].push_back(read()-1),y[now].push_back(read()-1),now=num;else if (T==2) now=pos[read()];else Qx[now].push_back(read()-1),Qy[now].push_back(read()),Qp[now].push_back(qn++); pos[i]=now; } dfs(0); //freopen("a.out","w",stdout); for (int i=0;i<qn;i++) printf("%d\n",mmh[i]==-1?-1:a[id[mmh[i]]]); }