并查集维护线段树合并
b加在a上
#include<iostream> #include<cstdio> #define ri register int #define u int namespace opt { inline u in() { u x(0),f(1); char s(getchar()); while(s<'0'||s>'9') { if(s=='-') f=-1; s=getchar(); } while(s>='0'&&s<='9') { x=(x<<1)+(x<<3)+s-'0'; s=getchar(); } return x*f; } } using opt::in; #define NN 100005 namespace xds { struct node { u l,r,sum,add; } a[NN<<6]; u num,ans[NN],rot[NN]; void pushdown(const u &rt,const u &l,const u &r) { if(a[rt].add) { if(!a[rt].l) a[rt].l=++num; if(!a[rt].r) a[rt].r=++num; u mid((l+r)>>1); a[a[rt].l].add+=a[rt].add; a[a[rt].r].add+=a[rt].add; a[a[rt].l].sum+=a[rt].add*(mid-l+1); a[a[rt].r].sum+=a[rt].add*(r-mid); a[rt].add=0; } } void update(u &rt,const u &l,const u &r,const u &x,const u &y,const u &k) { if(!rt) rt=++num; if(l>=x&&r<=y) { a[rt].sum+=k*(r-l+1),a[rt].add+=k; return; } pushdown(rt,l,r); u mid((l+r)>>1); if(x<=mid) update(a[rt].l,l,mid,x,y,k); if(y>=mid+1) update(a[rt].r,mid+1,r,x,y,k); a[rt].sum=a[a[rt].l].sum+a[a[rt].r].sum; } u query(const u &rt,const u &l,const u &r,const u &k) { if(k>a[rt].sum) return -1; if(l==r) return ans[l]; pushdown(rt,l,r); u mid((l+r)>>1); if(a[a[rt].l].sum>=k) return query(a[rt].l,l,mid,k); else return query(a[rt].r,mid+1,r,k-a[a[rt].l].sum); } void merge(u &x,const u &y) { if(!x||!y) { if(!x) x=y; return; } a[x].sum+=a[y].sum,a[x].add+=a[y].add; merge(a[x].l,a[y].l),merge(a[x].r,a[y].r); } } namespace cas { u fa[NN]; u getfa(u x) { u _x(x),k; while(_x^fa[_x]) _x=fa[_x]; while(x^_x) k=fa[x],fa[x]=_x,x=k; return _x; } } namespace mainstay { u v[NN]; using namespace cas; using namespace xds; inline void solve() { u N(in()),M(in()); for(ri i(1); i<=N; ++i) fa[i]=i; for(ri i(1); i<=N; ++i) v[i]=in(),ans[v[i]]=i,update(rot[getfa(i)],1,N,v[i],v[i],1); for(ri i(1); i<=M; ++i) { u _a(in()),_b(in()); if(getfa(_a)^getfa(_b)) { merge(rot[getfa(_a)],rot[getfa(_b)]); fa[getfa(_b)]=getfa(_a); } } u Q(in()); while(Q--) { char _s(getchar()); while(_s!='Q'&&_s!='B') _s=getchar(); u _a(in()),_b(in()); if(_s=='Q') { printf("%d\n",query(rot[getfa(_a)],1,N,_b)); } else { if(getfa(_a)^getfa(_b)) { merge(rot[getfa(_a)],rot[getfa(_b)]); fa[getfa(_b)]=getfa(_a); } } } } } int main() { //freopen("x.txt","r",stdin); //freopen("my.txt","w",stdout); std::ios::sync_with_stdio(false); mainstay::solve(); }