省选专练HAOI2015树上操作

题如其名

树链剖分板子题

#include<bits/stdc++.h>
using namespace std;
#define lc (p<<1)
#define rc (p<<1|1)
typedef int INT;
#define int long long
const int N=2e5+100;
inline void read(int &x){
	x=0;
	char ch=getchar();
	int f=1;
	while(ch<'0'||ch>'9'){
		if(ch=='-'){
			f=-1;
		}
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	x*=f;
}
struct Front_star{
	int u,v,nxt;
}e[N*4];
int cnt=1;
int first[N]={};
void addedge(int u,int v){
	cnt++;
	e[cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=first[u];
	first[u]=cnt;
}
void add(int u,int v){
	addedge(u,v);
	addedge(v,u);
}
int n,m;
int dep[N]={};
int siz[N]={};
int son[N]={};
int top[N]={};
int fa[N]={};
int tree[N]={};
int pre[N]={};
int idx=0;
struct Segment_Tree{
	int sum,lson,rson,addlazy;
}T[N<<2];
void dfs1(int u,int fat,int depth){
//	cout<<u<<" "<<'\n';
	dep[u]=depth;
	siz[u]=1;
	fa[u]=fat;
	for(int i=first[u];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==fat)continue;
		dfs1(v,u,depth+1);
		siz[u]+=siz[v];
		if(!son[u]||siz[son[u]]<siz[v]){
			son[u]=v;
		}
	}
}
void dfs2(int u,int tp){
//	cout<<u<<" "<<'\n';
	top[u]=tp;
	tree[u]=++idx;
	pre[idx]=u;
	if(!son[u])return;
	dfs2(son[u],tp);
	for(int i=first[u];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==fa[u]||v==son[u])continue;
		dfs2(v,v);
	}
}
int val[N]={};
void pushup(int p){
	T[p].sum=T[lc].sum+T[rc].sum;
}
void pushdown(int p){
	if(T[p].addlazy){
		T[lc].sum+=(T[lc].rson-T[lc].lson+1)*T[p].addlazy;
		T[rc].sum+=(T[rc].rson-T[rc].lson+1)*T[p].addlazy;
		T[lc].addlazy+=T[p].addlazy;
		T[rc].addlazy+=T[p].addlazy;
		T[p].addlazy=0;
	}
}
void build(int p,int l,int r){
	T[p].lson=l;
	T[p].rson=r;
	if(l==r){
		T[p].sum=val[pre[l]];
		T[p].addlazy=0;
		return;
	}
	int mid=(l+r)/2;
	build(lc,l,mid);
	build(rc,mid+1,r);
	pushup(p);
}
void update(int p,int dl,int dr,int val){
	if(dl<=T[p].lson&&T[p].rson<=dr){
		T[p].sum+=(T[p].rson-T[p].lson+1)*val;
		T[p].addlazy+=val;
		return;
	}
	pushdown(p);
	int mid=(T[p].lson+T[p].rson)/2;
	if(dl<=mid)update(lc,dl,dr,val);
	if(mid<dr)update(rc,dl,dr,val);
	pushup(p);
}
int query(int p,int dl,int dr){
	int ret=0;
	if(dl<=T[p].lson&&T[p].rson<=dr){
		return T[p].sum;
	}
	pushdown(p);
	int mid=(T[p].lson+T[p].rson)/2;
	if(dl<=mid)ret+=query(lc,dl,dr);
	if(mid<dr) ret+=query(rc,dl,dr);
	return ret;
}
int query_line(int x,int y){
	int ret=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		ret+=query(1,tree[top[x]],tree[x]);
		x=fa[top[x]];
	}
	if(tree[x]>tree[y])swap(x,y);
	ret+=query(1,tree[x],tree[y]);
	return ret;
}
INT main(){
//	freopen("P3178.c","r",stdin);
	read(n);
	read(m);
	for(int i=1;i<=n;i++){
		read(val[i]);
	}
	for(int i=1;i<n;i++){
		int u,v;
		read(u);
		read(v);
		add(u,v);
	}
	dfs1(1,0,1);
	dfs2(1,1);
//	for(int i=1;i<=n;i++)cout<<tree[i]<<" ";
	build(1,1,n);
//	cout<<query(1,1,n);
//	cout<<"working"<<'\n';
	while(m--){
		int opt,x;
		read(opt);
		read(x);
		if(opt==1){
			int val;
			read(val);
			update(1,tree[x],tree[x],val);
		}
		else{
			if(opt==2){
				int val;
				read(val);
				update(1,tree[x],tree[x]+siz[x]-1,val);
			}
			else{
				int sum=query_line(1,x);
				cout<<sum<<'\n';
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/80960796