[bzoj 2733]启发式合并权值线段树
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2733
平衡树待学习。从一个博客学到了合并权值线段树的姿势:http://blog.csdn.net/werkeytom_ftd/article/details/51761651
#include<bits/stdc++.h> using namespace std; const int maxn=100010; int read(){ int x=0; char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x; } char get(){ char ch=getchar(); while (ch!='Q'&&ch!='B') ch=getchar(); return ch; } struct Node { int val,lson,rson; }node[maxn+maxn*20]; int fa[maxn]; int a[maxn]; int b[maxn]; int tot; int n; int findfa(int u) { if (fa[u]==u) return u; else return fa[u]=findfa(fa[u]); } int rt[maxn]; void insert(int root,int k,int l,int r) { node[root].val++; if (l==r) return; int mid=(l+r)/2; if (k<=mid) { if (!node[root].lson) node[root].lson=++tot; insert(node[root].lson,k,l,mid); } else { if (!node[root].rson) node[root].rson=++tot; insert(node[root].rson,k,mid+1,r); } } int merge(int rt1,int rt2,int l,int r) { if (!rt2) return rt1; if (!rt1) return rt2; if (l==r) { node[rt1].val+=node[rt2].val; return rt1; } int mid=(l+r)/2; node[rt1].val+=node[rt2].val; node[rt1].lson=merge(node[rt1].lson,node[rt2].lson,l,mid); node[rt1].rson=merge(node[rt1].rson,node[rt2].rson,mid+1,r); return rt1; } int query(int root,int k,int l,int r) { if (l==r) return l; int mid=(l+r)/2; if (node[node[root].lson].val>=k) return query(node[root].lson,k,l,mid); else return query(node[root].rson,k-node[node[root].lson].val,mid+1,r); } void addedge(int u,int v) { int f1=findfa(u); int f2=findfa(v); if (f1!=f2) { fa[f2]=f1; rt[f1]=merge(rt[f1],rt[f2],1,n); } } int main() { // freopen("in.txt","r",stdin); int m; n=read(); m=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<=n;i++) b[a[i]]=i; for (int i=1;i<=n;i++) fa[i]=i; for (int i=1;i<=n;i++) rt[i]=++tot; for (int i=1;i<=n;i++) insert(rt[i],a[i],1,n); for (int i=0;i<m;i++) { int u,v; u=read(); v=read(); addedge(u,v); } int q; q=read(); while (q--) { char s; int u,v; s=get(); u=read(); v=read(); if (s=='B') addedge(u,v); else { int f=findfa(u); if (node[f].val<v) printf("-1\n"); else printf("%d\n",b[query(rt[f],v,1,n)]); } } return 0; }