算是线段树合并的模板题,不过好像用fhq做会更快(不管了)
用一个并查集维护合并的根,注意合并的时候,并查集合并要与线段树合并方向要一致。
算是很模板的一道题
#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
#define int long long
//#define double long double
#define re register int
#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define P pair < int , int >
#define mk make_pair
using namespace std;
const int mod=1e9+7;
const int M=1e8+5;
const int N=8e6+5;//?????????? 4e8
struct nod
{
int l,r,sum,id;
}e[N];
int n,fa[N],m,q;
int rt[N],tot;
int get(int x){ return fa[x]==x?x:fa[x]=get(fa[x]); }
void pushup(int p)
{
e[p].sum=e[e[p].l].sum+e[e[p].r].sum;
}
int insert(int p,int l,int r,int pos,int root)
{
if(!p) p=++tot;
e[p].sum++;
if(l==r)
{
e[p].id=root;
return p;
}
int mid=(l+r)>>1;
if(pos<=mid) e[p].l=insert(e[p].l,l,mid,pos,root);
else e[p].r=insert(e[p].r,mid+1,r,pos,root);
return p;
}
int merge(int p1,int p2,int l,int r)
{
if(!p1||!p2) return p1+p2;
if(l==r)
{
if(e[p2].id)
{
e[p1].sum+=e[p2].sum;
e[p1].id=e[p2].id;
}
return p1;
}
int mid=(l+r)>>1;
e[p1].l=merge(e[p1].l,e[p2].l,l,mid);
e[p1].r=merge(e[p1].r,e[p2].r,mid+1,r);
pushup(p1);
return p1;
}
int ask(int p,int l,int r,int k)
{
if(k>e[p].sum||!p) return -1;
if(l==r) return e[p].id;
int t=e[e[p].l].sum;
int mid=(l+r)>>1;
if(k<=t) return ask(e[p].l,l,mid,k);
return ask(e[p].r,mid+1,r,k-t);
}
void solve()
{
cin>>n>>m;
for(re i=1;i<=n;i++)
{
int x;
scanf("%lld",&x);
fa[i]=i;
rt[i]=insert(rt[i],1,n,x,i);
}
for(re i=1;i<=m;i++)
{
int x,y;
scanf("%lld%lld",&x,&y);
x=get(x),y=get(y);
if(x==y) continue;
fa[y]=x;
rt[x]=merge(rt[x],rt[y],1,n);
}
cin>>q;
while(q--)
{
char op[5];
int x,y;
scanf("%s%lld%lld",op,&x,&y);
x=get(x);
if(op[0]=='Q') printf("%lld\n",ask(rt[x],1,n,y));
else
{
y=get(y);
if(x==y) continue;
rt[x]=merge(rt[x],rt[y],1,n);
fa[y]=x;
}
}
}
signed main()
{
// freopen("P1505_1.txt", "r", stdin);
// freopen("Aout.txt", "w", stdout);
int T=1;
// cin>>T;
for(int index=1;index<=T;index++)
{
// printf("Case %d:\n",index);
solve();
// puts("");
}
return 0;
}
/*a
*/