[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);
posted @ 2021-04-18 14:13  fhq_treap  阅读(69)  评论(0编辑  收藏  举报