启发式合并
至今不知道时空复杂度怎么保证,从不证明算法复杂度,只会用大数据实测一下......
#include<cstdio> #include<cstdlib> #include<algorithm> #include<map> using namespace std; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } inline void read(char &x) { for (x=nc();x!='B' && x!='Q';x=nc()); } int n,m; int idx[100005]; int fat[100005],w[100005]; int size,root[100005],ls[1800005],rs[1800005],sum[1800005]; inline int getfat(int u){ return u==fat[u]?u:fat[u]=getfat(fat[u]); } inline void insert(int &rt,int l,int r,int val) { if (!rt) rt=++size; if (l==r){ sum[rt]=1; return; } int mid=(l+r)>>1; if (val<=mid) insert(ls[rt],l,mid,val); else insert(rs[rt],mid+1,r,val); sum[rt]=sum[ls[rt]]+sum[rs[rt]]; } inline int merge(int x,int y) { if (!x) return y; if (!y) return x; ls[x]=merge(ls[x],ls[y]); rs[x]=merge(rs[x],rs[y]); sum[x]=sum[ls[x]]+sum[rs[x]]; return x; } inline int query(int rt,int l,int r,int k) { if (l==r) return l; int mid=(l+r)>>1; if (k<=sum[ls[rt]]) return query(ls[rt],l,mid,k); else return query(rs[rt],mid+1,r,k-sum[ls[rt]]); } int main() { int _x,_y,fx,fy,Q; char order; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); for (int i=1;i<=n;i++) read(w[i]),idx[w[i]]=i; for (int i=1;i<=n;i++) fat[i]=i; for (int i=1;i<=m;i++) { read(_x),read(_y); fx=getfat(_x); fy=getfat(_y); fat[fx]=fy; } for (int i=1;i<=n;i++) insert(root[getfat(i)],1,n,w[i]); read(Q); while (Q--) { read(order); if (order=='B') { read(_x); read(_y); fx=getfat(_x); fy=getfat(_y); if (fx!=fy) { fat[fx]=fy; root[fy]=merge(root[fx],root[fy]); } } else if (order=='Q') { read(_x); fx=getfat(_x); read(_y); if (sum[root[fx]]<_y) printf("-1\n"); else printf("%d\n",idx[query(root[fx],1,n,_y)]); } } return 0; }