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;
}