思路:
1.线段树合并(nlogn的) 2.splay+启发式合并线段树合并比较好写
//By SiriusRen#include#include #include using namespace std;const int N=100050;int n,m,q,a[N],f[N],xx,yy,son[N*50][2],tr[N*50],root[N],cnt,rev[N];char op[10];int find(int x){ return x==f[x]?x:f[x]=find(f[x]);}void push_up(int x){ tr[x]=tr[son[x][0]]+tr[son[x][1]];}void insert(int &x,int l,int r,int wei){ if(!x)x=++cnt; if(l==r){ tr[x]++;return;} int mid=(l+r)>>1; if(mid >1; if(tr[son[x][0]]>=num)return query(son[x][0],l,mid,num); return query(son[x][1],mid+1,r,num-tr[son[x][0]]);}void add(){ int fx=find(xx),fy=find(yy); if(fx!=fy)root[fx]=merge(root[fx],root[fy]),f[fy]=fx; }int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i]),f[i]=i,insert(root[i],1,n,a[i]),rev[a[i]]=i; while(m--)scanf("%d%d",&xx,&yy),add(); scanf("%d",&q); while(q--){ scanf("%s%d%d",op,&xx,&yy); if(op[0]=='Q')printf("%d\n",tr[root[find(xx)]]