求助loj dfs序2
  • 板块学术版
  • 楼主Kniqht
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/9/24 22:35
  • 上次更新2023/11/2 18:13:30
查看原帖
求助loj dfs序2
315205
Kniqht楼主2023/9/24 22:35

树上区间加和区间求和

样例没过,都是负,但数字没炸

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+10;
int n,m;ll tr1[N],tr2[N];
int h[N],e[N],ne[N],idx,w[N];
int din[N],dout[N],id;
void add(int a,int b){
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int lowbit(int x){
	return x&(-x);
}
void add(ll tr[],int x,ll c){
	for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=c;
} 
ll sum(ll tr[],int x){
	ll res=0;
	for(int i=x;i;i-=lowbit(i)) res+=tr[i];
	return res;
}
ll query(int x){
	return sum(tr1,x)*(x+1)-sum(tr2,x);
}
void modify(int x,int y,ll k){
	add(tr1,x,k);add(tr1,y+1,-k);
	add(tr2,x,k*x);add(tr2,y+1,-k*(y+1));
}
void dfs(int x,int fa){
	din[x]=++id;
	for(int i=h[x];~i;i=ne[i]){
		int j=e[i];
		if(j==fa) continue;
		dfs(j,x);
	}
	dout[x]=++id;
}
int rt;
signed main(){
	memset(h,-1,sizeof(h));
	scanf("%d%d%d",&n,&m,&rt);
	for(int i=1;i<=n;i++) scanf("%lld",&w[i]);
	for(int i=1;i<n;i++){
		int a,b;scanf("%d%d",&a,&b);
		add(a,b);add(b,a);
	}
	dfs(rt,-1);
	for(int i=1;i<=n;i++) modify(din[i],din[i],w[i]);//使用函数封装,防止出错 
	while(m--){
		int opt,x;ll y;
		scanf("%d%d",&opt,&x);
		if(opt==1){
			scanf("%lld",&y);
			modify(din[x],dout[x],y);
		}
		else printf("%lld\n",query(dout[x])-query(din[x]-1));
	}
    return 0;
}

2023/9/24 22:35
加载中...