【BZOJ1146】网络管理(主席树,树状数组)

【BZOJ1146】网络管理(主席树,树状数组)

题面

BZOJ权限题,洛谷题面

题解

树上带修改主席树
貌似和\(Count\ On\ A\ Tree\)那题很相似呀
只需要套上一个树状数组来维护修改好就好了
但是记住是用\(dfs\)来记录主席树的标号
一定不要搞错了
每一次修改只会影响他子数的值
而在\(dfs\)序上就是连续的一段
美滋滋的做完了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 161000
inline int read()
{
    RG int x=0,t=1;RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int dfn[MAX],low[MAX],fa[MAX],size[MAX],hson[MAX],dep[MAX],top[MAX];
int tim,n,Q;
int S[MAX<<1],Tot,TT[MAX];
int lowbit(int x){return x&(-x);}
struct Node{int ls,rs,v;}t[MAX<<8];
int rt[MAX],tot,ln[MAX];
int LCA(int u,int v)
{
	while(top[u]!=top[v])
		dep[top[u]]<dep[top[v]]?v=fa[top[v]]:u=fa[top[u]];
	return dep[u]<dep[v]?u:v;
}
void Modify(int &now,int ff,int l,int r,int pos,int w)
{
	t[now=++tot]=t[ff];t[now].v+=w;
	if(l==r)return;
	int mid=(l+r)>>1;
	if(pos<=mid)Modify(t[now].ls,t[ff].ls,l,mid,pos,w);
	else Modify(t[now].rs,t[ff].rs,mid+1,r,pos,w);
}
void PreModify(int K,int pos,int w){for(int i=K;i<=n;i+=lowbit(i))Modify(rt[i],rt[i],1,Tot,pos,w);}
int tmp1[MAX<<1],tmp2[MAX<<1],t1,t2;
int Query(int l,int r,int K)
{
	if(l==r)return l;
	int mid=(l+r)>>1,ss=0;
	for(int i=1;i<=t1;++i)ss+=t[t[tmp1[i]].rs].v;
	for(int i=1;i<=t2;++i)ss-=t[t[tmp2[i]].rs].v;
	if(ss>=K)
	{
		for(int i=1;i<=t1;++i)tmp1[i]=t[tmp1[i]].rs;
		for(int i=1;i<=t2;++i)tmp2[i]=t[tmp2[i]].rs;
		return Query(mid+1,r,K);
	}
	else
	{
		for(int i=1;i<=t1;++i)tmp1[i]=t[tmp1[i]].ls;
		for(int i=1;i<=t2;++i)tmp2[i]=t[tmp2[i]].ls;
		return Query(l,mid,K-ss);
	}
}
int preQuery(int u,int v,int K)
{
	t1=t2=0;
	for(int i=dfn[u];i;i-=lowbit(i))tmp1[++t1]=rt[i];
	for(int i=dfn[v];i;i-=lowbit(i))tmp1[++t1]=rt[i];
	int lca=LCA(u,v);
	for(int i=dfn[lca];i;i-=lowbit(i))tmp2[++t2]=rt[i];
	for(int i=dfn[fa[lca]];i;i-=lowbit(i))tmp2[++t2]=rt[i];
	return Query(1,Tot,K);
}
void dfs1(int u,int ff)
{
	size[u]=1;fa[u]=ff;dep[u]=dep[ff]+1;
	for(int i=h[u];i;i=e[i].next)
	{
		if(e[i].v==ff)continue;
		dfs1(e[i].v,u);
		size[u]+=size[e[i].v];
		if(size[e[i].v]>size[hson[u]])hson[u]=e[i].v;
	}
}
void dfs2(int u,int tp)
{
	top[u]=tp;dfn[u]=++tim;ln[tim]=u;
	if(hson[u])dfs2(hson[u],tp);
	for(int i=h[u];i;i=e[i].next)
	{
		if(e[i].v==fa[u]||e[i].v==hson[u])continue;
		dfs2(e[i].v,e[i].v);
	}
	low[u]=tim;
}
void dfs3(int u,int ff)
{
	PreModify(dfn[u],TT[u],1);
	PreModify(low[u]+1,TT[u],-1);
	for(int i=h[u];i;i=e[i].next)
		if(e[i].v!=ff)dfs3(e[i].v,u);
}
struct Op{int k,a,b;}O[MAX];
int main()
{
	n=read();Q=read();
	for(int i=1;i<=n;++i)S[++Tot]=TT[i]=read();
	for(int i=1;i<n;++i)
	{
		int u=read(),v=read();
		Add(u,v);Add(v,u);
	}
	for(int i=1;i<=Q;++i)O[i].k=read(),O[i].a=read(),O[i].b=read();
	for(int i=1;i<=Q;++i)if(O[i].k==0)S[++Tot]=O[i].b;
	sort(&S[1],&S[Tot+1]);
	Tot=unique(&S[1],&S[Tot+1])-S-1;
	for(int i=1;i<=n;++i)TT[i]=lower_bound(&S[1],&S[Tot+1],TT[i])-S;
	for(int i=1;i<=Q;++i)if(O[i].k==0)O[i].b=lower_bound(&S[1],&S[Tot+1],O[i].b)-S;
	dfs1(1,0);dfs2(1,1);dfs3(1,1);
	for(int i=1;i<=Q;++i)
	{
		if(O[i].k==0)
		{
			PreModify(dfn[O[i].a],TT[O[i].a],-1);
			PreModify(low[O[i].a]+1,TT[O[i].a],1);
			PreModify(dfn[O[i].a],O[i].b,1);
			PreModify(low[O[i].a]+1,O[i].b,-1);
			TT[O[i].a]=O[i].b;
		}
		else
		{
			int len=dep[O[i].a]+dep[O[i].b]-2*dep[LCA(O[i].a,O[i].b)]+1;
			if(O[i].k>len){puts("invalid request!");continue;}
			printf("%d\n",S[preQuery(O[i].a,O[i].b,O[i].k)]);
		}
	}
	return 0;	
}

posted @ 2018-02-05 09:08  小蒟蒻yyb  阅读(499)  评论(0编辑  收藏  举报