ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P3178 [HAOI2015]树上操作

2021-11-18 09:33:45  阅读:207  来源: 互联网

标签:P3178 return int mid HAOI2015 tag read ans 树上


操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

树剖板子

const int N=1e5+79;
int a[N],b[N];
int n,m;

struct graph{
	int head[N],tot,next[N<<1],ver[N<<1];
	inline void add(int a,int b){
		ver[++tot]=b;
		next[tot]=head[a];
		head[a]=tot;
	}
}G;
int top[N],dep[N],fa[N],son[N],siz[N],dfn[N],tim;
inline void dfs1(int x){
	siz[x]=1;
	dep[x]=dep[fa[x]]+1;
	repg(x){
		int y(G.ver[i]);
		if(y==fa[x]) continue;
		fa[y]=x;
		dfs1(y);
		siz[x]+=siz[y];
		if(siz[son[x]]<siz[y]){
			son[x]=y;
		}
	}
}
inline void dfs2(int x,int topf){
	dfn[x]=++tim;
	b[tim]=a[x];
	top[x]=topf;
	if(son[x]){
		dfs2(son[x],topf);
	}
	repg(x){
		int y(G.ver[i]);
		if(y==son[x]||y==fa[x]) continue;
		dfs2(y,y);
	}
}

struct SegmentTree{
	int lc[N<<2],rc[N<<2];
	lxl sum[N<<2],tag[N<<2];
	int cnt,rt;
	inline void pushup(int p){
		sum[p]=sum[lc[p]]+sum[rc[p]];
	}
	inline void pushdown(int &p,int L,int R){
		if(!tag[p]) return ;
		int mid(L+R>>1);
		if(lc[p]){
			sum[lc[p]]+=(mid-L+1)*tag[p];
			tag[lc[p]]+=tag[p];
		}
		if(rc[p]){
			sum[rc[p]]+=(R-mid)*tag[p];
			tag[rc[p]]+=tag[p];
		}
		tag[p]=0;
	}
	inline void build(int &p,int L,int R){
		if(!p) p=++cnt;
		if(L==R){
			sum[p]=b[L];
			return ;
		}
		int mid(L+R>>1);
		build(lc[p],L,mid);
		build(rc[p],mid+1,R);
		pushup(p);
	}
	inline void change(int &p,int L,int R,int ll,int rr,lxl val){
		if(!p) p=++cnt;
		if(ll<=L&&rr>=R){
			sum[p]+=(R-L+1)*val;
			tag[p]+=val;
			return;
		}
		pushdown(p,L,R);
		int mid(L+R>>1);
		if(ll<=mid) change(lc[p],L,mid,ll,rr,val);
		if(rr>mid) change(rc[p],mid+1,R,ll,rr,val);
		pushup(p);
	}inline lxl query(int &p,int L,int R,int ll,int rr){
		if(!p) return 0;
		
		if(ll<=L&&rr>=R){
			return sum[p];
		}
		pushdown(p,L,R);
		int mid(L+R>>1);
		lxl ans(0);
		if(ll<=mid) ans+=query(lc[p],L,mid,ll,rr);
		if(rr>mid) ans+=query(rc[p],mid+1,R,ll,rr);
		return ans;
	}
}S;
inline lxl Qchain(int x,int y){
	lxl ans(0);
	while(top[x]^top[y]){
		if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
		ans+=S.query(S.rt,1,n,dfn[top[x]],dfn[x]);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) std::swap(x,y);
	ans+=S.query(S.rt,1,n,dfn[x],dfn[y]);
	return ans;
}
/*
5 1
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
*/
int main(){
	read(n);read(m);
	rep(i,1,n){
		read(a[i]);
	}
	int a,y;
    rep(i,2,n){
    	read(a);read(y);
    	G.add(a,y);
    	G.add(y,a);
	}
	
	dfs1(1);
	
	dfs2(1,1);
	S.build(S.rt,1,n);
	
	
	int op,x;
	rep(i,1,m){
		read(op);
		if(op==1){
			read(x);read(a);
			S.change(S.rt,1,n,dfn[x],dfn[x],a);
		}else if(op==2){
				read(x);read(a);
			S.change(S.rt,1,n,dfn[x],dfn[x]+siz[x]-1,a);
		}else {
			read(x);
			out(Qchain(1,x),'\n');
		}
	}
	return 0;
}

标签:P3178,return,int,mid,HAOI2015,tag,read,ans,树上
来源: https://www.cnblogs.com/QQ2519/p/15570774.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有