F. 数学上来先打表
题解:
搞这题搞了一天
思维不是很难
就是暴力压位bitset
分块做法速度更快
但是stl里的不能实现这个功能
所以手动实现
64位压一位
到65535跑一下1的个数
然后(x>>16)&65535+...计算出1的个数
眼查错果然还是不靠谱以后还是写对拍吧
另外的难点在于这题很卡空间
我们建立dfs树
这样把总空间变为最大消耗空间
合并bitset的时候我们利用启发式合并
并且bitset只存出现了的位置
就是那些64位都没有出现的就不存了
空间是nlogn的,但是还是挺卡的吧
使用动态开数组的技巧替代vector
*int=calloc(大小,sizeof())
另外这个东西不会自动释放空间
所以我们要free()这个东西
代码:
#include <bits/stdc++.h> using namespace std; #define ull unsigned long long #define ll long long #define rint int #define IL inline #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) const int N=1.1e5; struct bi{ ull *v; int *pos,cnt; bi() { cnt=0;} }B[N]; int head[N],count2[N],count3[N],pos[N],pos2[N],pos3[N],pos4[N],fa[N],ans[N]; IL void js2(bi &a,bi b,int p) { if (p==34319) { int sad; sad=0; } bi c; int tmp=a.cnt+b.cnt; c.v=(ull*)calloc(tmp+2,sizeof(ull)); c.pos=(int*)calloc(tmp+2,sizeof(int)); rint x=a.cnt,y=b.cnt; c.cnt=0; rint i=1,j=1; while (i<=x&&j<=y) { if (a.pos[i]<b.pos[j]) c.v[++c.cnt]=a.v[i],c.pos[c.cnt]=a.pos[i],i++; else if (a.pos[i]>b.pos[j]) c.v[++c.cnt]=b.v[j],c.pos[c.cnt]=b.pos[j],j++; else { // if (a.v[i]^b.v[j]) c.v[++c.cnt]=a.v[i]^b.v[j],c.pos[c.cnt]=b.pos[j]; i++; j++; } } while (j<=y) c.v[++c.cnt]=b.v[j],c.pos[c.cnt]=b.pos[j],j++; while (i<=x) c.v[++c.cnt]=a.v[i],c.pos[c.cnt]=a.pos[i],i++; free(a.v); free(a.pos); a=c; } struct re{ int a,b,c,d; }e[N*2],a[N]; bool cmp(re x,re y) { return(x.a<y.a); } int l; void arr(int x,int y,int x1,int y1) { e[++l].a=head[x]; e[l].b=y; e[l].c=x1; e[l].d=y1; head[x]=l; } #define js(x) (count2[x&65535]+count2[(x>>16)&65535]+count2[(x>>32)&65535]+count2[(x>>48)&65535]) int find(int x) { return fa[x]==x?x:find(fa[x]); } vector<re> ve[N]; void dfs(int x) { int l=(int)(ve[x].size())-1; rep(i,0,l) { int x1=pos4[find(ve[x][i].a)],x2=ve[x][i].b,x3=ve[x][i].c; int cnt=0; rep(i,1,B[x1].cnt) if (cnt+js(B[x1].v[i])<x2) cnt+=js(B[x1].v[i]); else { ull o=B[x1].v[i]; rep(j,0,63) if ((o>>j)&1) { cnt++; if (cnt==x2) { ans[x3]=64*(B[x1].pos[i]-1)+j+1; break; } } break; } if (cnt<x2) ans[x3]=-1; } for (rint u=head[x];u;u=e[u].a) { rint v=e[u].b; rint x1=find(e[u].c),x2=find(e[u].d),tmp=0; // bi tmp2; bool tt=0; if (x1!=x2) { tt=1; if (count3[x1]>count3[x2]) swap(x1,x2); fa[x1]=x2; count3[x2]+=count3[x1]; int k1=B[pos4[x1]].cnt,k2=B[pos4[x2]].cnt; if (k1>k2) { tmp=pos4[x2]; // tmp2=B[pos4[x1]]; js2(B[pos4[x1]],B[pos4[x2]],1); pos4[x2]=pos4[x1]; } else js2(B[pos4[x2]],B[pos4[x1]],pos4[x2]); } dfs(v); if (tt) { fa[x1]=x1; count3[x2]-=count3[x1]; if (tmp) { pos4[x2]=tmp; js2(B[pos4[x1]],B[tmp],1); } else { js2(B[pos4[x2]],B[pos4[x1]],pos4[x2]); } } } } int main() { ios::sync_with_stdio(false); rep(i,0,65536) count2[i]=count2[i>>1]+(i&1); int n,m; cin>>n>>m; rep(i,1,n) cin>>a[i].a,a[i].b=i; rep(i,1,n) pos4[i]=i,count3[i]=1; sort(a+1,a+n+1,cmp); rep(i,1,n) pos[a[i].b]=i,pos2[i]=a[i].a; rep(i,1,n) { B[i].v=(ull*)calloc(2,sizeof(ull)); B[i].pos=(int*)calloc(2,sizeof(int)); int t=pos[i]; t--; B[i].pos[1]=(t/64)+1; B[i].v[1]=1ull<<(t%64); fa[i]=i; B[i].cnt=1; } int now,cnt,cnt2=0; now=cnt=1; pos3[0]=1; rep(i,1,m) { int kk,x,y; cin>>kk; if (kk==1) { cin>>x>>y; arr(now,++cnt,x,y); pos3[i]=cnt; now=cnt; } if (kk==2) { cin>>x; now=pos3[x]; } if (kk==3) { cin>>x>>y; ve[now].push_back((re){x,y,++cnt2}); } pos3[i]=now; } dfs(1); rep(i,1,cnt2) if (ans[i]==-1) cout<<-1<<endl; else cout<<pos2[ans[i]]<<endl; return 0; }