AtCoder Beginner Contest 243
阿新 • • 發佈:2022-03-14
十年前的省選題目,放到現在來看可謂足夠簡單。線段樹合併模板加基礎並查集,沒什麼好說的。
#include<cstdio> //#define zczc const int N=100010; inline void read(int &wh){ wh=0;int f=1;char w=getchar(); while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();} while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();} wh*=f;return; } inline bool op(){ char w=getchar(); while(w!='Q'&&w!='B')w=getchar(); return w=='B'; } int m,n,q,cnt,f[N],root[N]; inline int find(int wh){return f[wh]==wh?wh:f[wh]=find(f[wh]);} #define lc t[x].l #define rc t[x].r #define mid (l+r>>1) struct node{int l,r,data,id;}t[N<<5]; inline void pushup(int x){ t[x].data=t[lc].data+t[rc].data; } int insert(int x,int l,int r,int pl,int id){ if(!x)x=++cnt;if(l==r)return t[x].data++,t[x].id=id,x; if(pl<=mid)lc=insert(lc,l,mid,pl,id); else rc=insert(rc,mid+1,r,pl,id); pushup(x);return x; } int merge(int x,int y,int l,int r){ if(!x)return y;if(!y)return x; if(l==r)return t[x].data+=t[y].data,x; lc=merge(lc,t[y].l,l,mid); rc=merge(rc,t[y].r,mid+1,r); pushup(x);return x; } int work(int x,int l,int r,int want){ if(want>t[x].data)return -1; if(l==r)return t[x].id; return t[lc].data>=want?work(lc,l,mid,want):work(rc,mid+1,r,want-t[lc].data); } #undef lc #undef rc #undef mid signed main(){ #ifdef zczc freopen("in.txt","r",stdin); #endif read(m);read(n);int s1,s2; for(int i=1;i<=m;i++){f[i]=i;read(s1);root[i]=insert(0,1,m,s1,i);} for(int i=1;i<=n;i++){ read(s1);read(s2);int f1=find(s1),f2=find(s2);if(f1==f2)continue; root[f1]=merge(root[f1],root[f2],1,m);f[f2]=f1; } read(q); while(q--){ if(op()){ read(s1);read(s2);int f1=find(s1),f2=find(s2);if(f1==f2)continue; root[f1]=merge(root[f1],root[f2],1,m);f[f2]=f1; } else{ read(s1);read(s2);s1=find(s1); printf("%d\n",work(root[s1],1,m,s2)); } } return 0; }