Code:
#include <cstdio> #include <algorithm> #include <cmath> using namespace std; #define ls lson[x] #define rs rson[x] #define setIO(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) const int maxn=500000; const int N=1000000000; namespace IO { char *p1,*p2,buf[100000]; #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++) int rd() { int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x; } }; struct UFS { int p[maxn]; void init() { for(int i=0;i<maxn;++i) p[i]=i; } int find(int x) { return p[x]==x?x:p[x]=find(p[x]); } }tr; int cnt; int rt[maxn],lson[maxn*10],rson[maxn*10],num[maxn*10]; double de[maxn*10]; int newnode() { return ++cnt; } void pushup(int x) { num[x]=num[ls]+num[rs]; de[x]=de[ls]+de[rs]; } void update(int &x,int l,int r,int p,int v) { if(!x)x=newnode(); if(l==r) { num[x]+=v, de[x]+=(double)v*(double)(log(p)); return; } int mid=(l+r)>>1; if(p<=mid) update(ls,l,mid,p,v); else update(rs,mid+1,r,p,v); pushup(x); } int merge(int x,int y) { if(!x||!y) return x+y; num[x]+=num[y]; de[x]+=de[y]; lson[x]=merge(lson[x],lson[y]); rson[x]=merge(rson[x],rson[y]); return x; } int less(int &x,int l,int r,int k) { if(!x||l>=k) return 0; int re=0; if(r<k) { re=num[x],x=0; return re; } if(l==r) return 0; int mid=(l+r)>>1; re+=less(ls,l,mid,k); re+=less(rs,mid+1,r,k); pushup(x); return re; } int bigger(int &x,int l,int r,int k) { if(!x||r<=k) return 0; int re=0; if(l>k) { re=num[x],x=0; return re; } if(l==r) return 0; int mid=(l+r)>>1; re+=bigger(ls,l,mid,k); re+=bigger(rs,mid+1,r,k); pushup(x); return re; } int kth(int x,int l,int r,int k) { if(l==r) return l; int mid=(l+r)>>1; if(k>num[ls]) return kth(rs,mid+1,r,k-num[ls]); else return kth(ls,l,mid,k); } int main() { using namespace IO; int m,cc=0; m=rd(); tr.init(); for(int cas=1;cas<=m;++cas) { int op=rd(); if(op==1) { int x=rd(); ++cc; update(rt[cc],1,N,x,1); } if(op==2) { int x,y,a,b; x=rd(),y=rd(); a=tr.find(x),b=tr.find(y); if(a!=b) { rt[b]=merge(rt[a],rt[b]); tr.p[a]=b; } } if(op==3) { int a,x,c=0; a=rd(),x=rd(); a=tr.find(a); c=less(rt[a],1,N,x); update(rt[a],1,N,x,c); } if(op==4) { int a,x,c=0; a=rd(),x=rd(); a=tr.find(a); c=bigger(rt[a],1,N,x); update(rt[a],1,N,x,c); } if(op==5) { int a,k; a=rd(),k=rd(); a=tr.find(a); printf("%d\n",kth(rt[a],1,N,k)); } if(op==6) { int a,b; a=rd(),b=rd(); a=tr.find(a),b=tr.find(b); if(de[rt[a]]>de[rt[b]]) printf("1\n"); else printf("0\n"); } if(op==7) { int a; a=rd(); a=tr.find(a); printf("%d\n",num[rt[a]]); } } return 0; }
原文:https://www.cnblogs.com/guangheli/p/11275836.html