[HNOI2012]永无乡
权值线段树合并裸题。
[HNOI2012]永无乡
#include<iostream>
#include<cstdio>
#define ll long long
#define N 100005
ll head[N];
ll n,m;
ll v[N << 5],ls[N << 5],rs[N << 5],fa[N],cnt,t[N << 5];
inline void up(ll now){v[now] = v[ls[now]] + v[rs[now]];}
inline ll get(ll now){return now == fa[now] ? now : fa[now] = get(fa[now]);}
#define mid ((l + r) >> 1)
ll tag;
inline int build(int l,int r,int to){
int now = ++cnt;
// std::cout<<now<<" "<<l<<" "<<r<<std::endl;
if(l == r){
t[now] = tag;
v[now] = 1;
return now;
}
if(to <= mid)
ls[now] = build(l,mid,to);
else
rs[now] = build(mid + 1,r,to);
up(now);
return now;
}
inline int merge(ll a,ll b,ll l,ll r){
// std::cout<<a<<" "<<b<<" "<<l<<" "<<r<<std::endl;
if(!a || !b)
return a + b;
if(l == r){
v[a] += v[b];
return a;
}
ls[a] = merge(ls[a],ls[b],l,mid);
rs[a] = merge(rs[a],rs[b],mid + 1,r);
up(a);
return a;
}
inline int Q(ll now,ll q,ll l,ll r){
// std::cout<<now<<" "<<q<<" "<<l<<" "<<r<<" "<<v[now]<<" "<<std::endl;
if(l == 1 && r == n && q > v[now])
return -1;
if(l == r)
return t[now];
if(v[ls[now]] >= q)
return Q(ls[now],q,l,mid);
else
return Q(rs[now],q - v[ls[now]],mid + 1,r);
}
inline void dfs(ll now,ll l,ll r){
if(now){
// std::cout<<now<<" "<<l<<" "<<r<<" "<<v[now]<<std::endl;
dfs(ls[now],l,mid);
dfs(rs[now],mid + 1,r);
}
}
int main(){
scanf("%lld%lld",&n,&m);
for(int i = 1;i <= n;++i)
fa[i] = i;
for(int i = 1;i <= n;++i){
ll x ;
scanf("%lld",&x);
tag = i;
head[i] = build(1,n,x);
}
for(int i = 1;i <= m;++i){
ll x,y;
scanf("%lld%lld",&x,&y);
ll fx = get(x),fy = get(y);
if(fx != fy){
// std::cout<<fx<<" "<<fy<<" "<<head[fx]<<" "<<head[fy]<<std::endl;
fa[fx] = fy;
head[fy] = merge(head[fx],head[fy],1,n);
}
}
ll q;
scanf("%lld",&q);
while(q -- ){
char s;
while(s != 'Q' && s != 'B')
s = getchar();
ll x,y;
scanf("%lld%lld",&x,&y);
if(s == 'B'){
ll fx = get(x),fy = get(y);
if(fx != fy){
// std::cout<<fx<<" "<<fy<<" "<<head[fx]<<" "<<head[fy]<<std::endl;
fa[fx] = fy;
head[fy] = merge(head[fx],head[fy],1,n);
}
}
else{
ll fx = get(x);
std::cout<<Q(head[fx],y,1,n)<<std::endl;
}
s = 'P';
}
}
return Q(rs[now],q - v[ls[now]],mid + 1,r);
与
return Q(rs[now],q - ls[now],mid + 1,r);