雾,全部re求助orz,关注奉上(树剖
查看原帖
雾,全部re求助orz,关注奉上(树剖
524801
不食嗟来之食楼主2022/10/13 11:35
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int N=1e5+5;
typedef long long ll;
int c[N],d[N],b[N],tot[N],fa[N],son[N],idx[N],cnt,top[N];
vector<int> e[N];
int n,q;
void dfs1(int u,int f) {
	d[u]=d[f]+1;
	tot[u]=1;
	fa[u]=f;
	for(auto v:e[u]) {
		dfs1(v,u);
		tot[u]+=tot[v];
		if(tot[v]>tot[son[u]]) son[u]=v;
	}
	return ;
}
void dfs2(int u,int topf) {
	idx[u]=++cnt;
	top[u]=topf;
	c[cnt]=b[u];
	if(son[u]) {
		dfs2(son[u],topf);
	}
	for(auto v:e[u]) {
		if(!idx[v]) {
			dfs2(v,v);
		}
	}
	return ;
}
struct peo {
	ll sum,lazy;
	int l,r;
} a[N<<2];
#define lson k<<1
#define rson k<<1|1
void push_up(int k) {
	a[k].sum=a[lson].sum+a[rson].sum;
}
void build(int k,int l,int r) {
	a[k].l=l,a[k].r=r;
	if(l==r) {
		a[k].sum=c[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	push_up(k);
	return ;
}
void push_down(int k) {
	if(a[k].lazy) {
		a[lson].lazy+=a[k].lazy;
		a[rson].lazy+=a[k].lazy;
		a[lson].sum+=(a[lson].r-a[lson].l+1)*a[k].lazy;
		a[rson].sum+=(a[rson].r-a[rson].l+1)*a[k].lazy;
		a[k].lazy=0;
	}
	return ;
}
void add(int k,int l,int r,ll val) {
	if(a[k].l>=l&&a[k].r<=r) {
		a[k].lazy+=val;
		a[k].sum+=(a[k].r-a[k].l+1)*val;
		return ;
	}
	push_down(k);
	int mid=(a[k].l+a[k].r)>>1;
	if(l<=mid) add(lson,l,r,val);
	if(r> mid) add(rson,l,r,val);
	push_up(k);
	return ;
}
ll sum(int k,int l,int r){
	if(a[k].l>=l&&a[k].r<=r) {
		return a[k].sum;
	}
	push_down(k);
	ll ans=0;
	int mid=(a[k].l+a[k].r)>>1;
	if(l<=mid) ans+=sum(lson,l,r);
	if(r> mid) ans+=sum(rson,l,r);
	push_up(k);
	return ans;
}
ll isum(int x,int y){
	ll ans=0;
	while(top[x]!=top[y]){
		if(d[top[x]]<d[top[y]]) swap(x,y);
		ans+=sum(1,idx[top[x]],idx[x]);
		x=fa[x];
	}
	if(d[x]>d[y]) swap(x,y);
	ans+=sum(1,idx[x],idx[y]);
	return ans;
}
int main() {
	freopen("P3178_1.in","r",stdin);
	scanf("%d%d",&n,&q);
	for(int i=1; i<=n; i++ )scanf("%d",&b[i]);
	for(int i=1; i<=n-1; i++) {
		int u,v;
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);
	for(int i=1;i<=q;i++){
		int opt;
		scanf("%d",&opt);
		switch(opt){
			case 1:{
				int x;
				ll val;
				scanf("%d%lld",&x,&val);
				add(1,idx[x],idx[x],val);
				break;
			}
			case 2:{
				int x;
				ll val;
				scanf("%d%lld",&x,&val);
				add(1,idx[x],idx[x]+tot[x]-1,val);
				break;
			}
			case 3:{
				int x;
				ll val;
				scanf("%d",&x);
				printf("%lld\n",isum(1,x));
				break;
			}
		}
	}
}
2022/10/13 11:35
加载中...