zoukankan      html  css  js  c++  java
  • [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);
    
  • 相关阅读:
    C# 添加修改防火墙端口及程序
    Winform 多线程--解决界面卡死问题
    ScreenOper
    KVM的VPS主机在Centos6.x下修改系统时间
    Java IO和File类
    Java动态代理Proxy类源码分析
    Java IO之字节流
    Java IO之字符流
    两台计算机之间如何通讯
    Java引用类型原理
  • 原文地址:https://www.cnblogs.com/dixiao/p/14673363.html
Copyright © 2011-2022 走看看