其他分享
首页 > 其他分享> > BZOJ 1146: [CTSC2008]网络管理Network 带修改主席树_树套树_DFS序

BZOJ 1146: [CTSC2008]网络管理Network 带修改主席树_树套树_DFS序

作者:互联网

Code:

#include<bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin) ,freopen(s".out","w",stdout) 
#define maxn 200000 
#define N 180000
using namespace std;      
int n,q, edges,cc,num; 
//权值线段树  
namespace Seg
{ 
	#define mid ((l+r)>>1)        
	int rt[maxn],node[10][maxn],cnt[10]; 
	int tot; 
	struct Node
	{
		int l,r,w; 
	}t[maxn*50]; 
	void insert(int &x,int l,int r,int k,int delta)
	{
		if(!x) x=++tot; 
		t[x].w+=delta;
		if(l==r) return; 
		if(k<=mid) 
            insert(t[x].l,l,mid,k,delta); 
		else 
            insert(t[x].r,mid+1,r,k,delta); 
	}
	int lowbit(int t)
	{
		return t & (-t); 
	}
	void update(int pos,int val,int delta)
	{           
		while(pos<=N) insert(rt[pos],1,N,val,delta),pos+=lowbit(pos);      
	}      
	int query(int l,int r,int kth)
	{
		if(l==r) return l;       
		int sum=0;                         
		for(int i=1;i<=cnt[0];++i)  sum+=t[t[node[0][i]].r].w;
		for(int i=1;i<=cnt[1];++i)  sum+=t[t[node[1][i]].r].w;
		for(int i=1;i<=cnt[2];++i)  sum-=t[t[node[2][i]].r].w;
		for(int i=1;i<=cnt[3];++i)  sum-=t[t[node[3][i]].r].w;
		if(sum < kth) 
		{
			for(int i=1;i<=cnt[0];++i)  node[0][i] = t[node[0][i]].l;            
			for(int i=1;i<=cnt[1];++i)  node[1][i] = t[node[1][i]].l; 
			for(int i=1;i<=cnt[2];++i)  node[2][i] = t[node[2][i]].l; 
			for(int i=1;i<=cnt[3];++i)  node[3][i] = t[node[3][i]].l; 
			return query(l,mid,kth-sum); 
		}
		else 
		{
			for(int i=1;i<=cnt[0];++i)  node[0][i] = t[node[0][i]].r; 
			for(int i=1;i<=cnt[1];++i)  node[1][i] = t[node[1][i]].r; 
			for(int i=1;i<=cnt[2];++i)  node[2][i] = t[node[2][i]].r; 
			for(int i=1;i<=cnt[3];++i)  node[3][i] = t[node[3][i]].r; 
			return query(mid+1,r,kth); 
		}
	} 
    // 关键字 : 位置 
	int Query(int a,int b,int c,int d,int kth)
	{
        cnt[0]=cnt[1]=cnt[2]=cnt[3]=0; 
		for(int i=a;i>0;i-=lowbit(i)) node[0][++cnt[0]] = rt[i];          
		for(int i=b;i>0;i-=lowbit(i)) node[1][++cnt[1]] = rt[i]; 
		for(int i=c;i>0;i-=lowbit(i)) node[2][++cnt[2]] = rt[i]; 
		for(int i=d;i>0;i-=lowbit(i)) node[3][++cnt[3]] = rt[i]; 
		return query(1,N,kth); 
	}
}; 
struct Query
{
	int opt,a,b; 
}Q[maxn];            
int hd[maxn],to[maxn],nex[maxn],dfs[maxn],arr[maxn],A[maxn];
int st[maxn],ed[maxn],F[20][maxn],dep[maxn],val[maxn];     
void add(int u,int v)
{
	nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; 
}
//read and diskreat 
void read()
{
	scanf("%d%d",&n,&q); 
	for(int i=1;i<=n;++i) scanf("%d",&val[i]),A[++cc]=val[i]; 
	for(int i=1,a,b;i<n;++i) 
		scanf("%d%d",&a,&b), add(a,b),add(b,a); 
	for(int i=1;i<=q;++i) 
	{
		scanf("%d%d%d",&Q[i].opt,&Q[i].a,&Q[i].b);  
		if(Q[i].opt==0) A[++cc]=Q[i].b; 
	}
	sort(A+1,A+1+cc); 
	for(int i=1;i<=q;++i)  if(Q[i].opt==0) Q[i].b=lower_bound(A+1,A+1+cc,Q[i].b)-A;       
	for(int i=1;i<=n;++i)  val[i] = lower_bound(A+1,A+1+cc,val[i])-A;  
}
//求dfs序
void DFS(int u,int fa)
{
	F[0][u]=fa, dep[u] = dep[fa] + 1;  
	for(int i=1;i<20;++i)  F[i][u]=F[i-1][F[i-1][u]]; 
	dfs[++num]=val[u],st[u]=num; 
	for(int i=hd[u];i;i=nex[i])
	{
		if(to[i]==fa) continue; 
		DFS(to[i],u); 
	}
	ed[u]=num+1; 
} 
int LCA(int a,int b)
{
	if(dep[b]<dep[a]) swap(a,b); 
	if(dep[a]!=dep[b])
	{
		for(int i=19;i>=0;--i) if(dep[F[i][b]] >= dep[a]) b = F[i][b]; 
	}
    if(a==b) return a; 
    for(int i=19;i>=0;--i)
    {
    	if(F[i][a]!=F[i][b]) a = F[i][a], b = F[i][b]; 
    }
    return F[0][a]; 
}
int main()
{
	// setIO("input"); 
	read();
	DFS(1,0);         
	for(int i = 1;i <= n; ++i)    
	{
		Seg::update(st[i],val[i], 1); 
		Seg::update(ed[i],val[i], -1); 
	}
	for(int i=1,a,b;i<=q;++i) 
	{
		a = Q[i].a, b = Q[i].b; 
		if(Q[i].opt==0) 
		{     
			Seg::update(st[a], val[a], -1);           
			Seg::update(ed[a], val[a], 1); 
			val[a] = b; 
			Seg::update(st[a],val[a], 1);  
			Seg::update(ed[a],val[a], -1); 
		}      
		if(Q[i].opt>0) 
		{ 
			int lca = LCA(a,b);                 
			int c = Seg::Query(st[a],st[b],st[lca],st[F[0][lca]],Q[i].opt); 
			if(c==1) 
                printf("invalid request!\n"); 
			else 
                printf("%d\n",A[c]);      
		}
	}
	return 0; 
}

  

标签:node,rt,cnt,1146,Network,int,DFS,++,maxn
来源: https://www.cnblogs.com/guangheli/p/10954819.html