树状数组,倒序dfs0分
查看原帖
树状数组,倒序dfs0分
1270559
zkhehe楼主2024/10/3 11:29
#include <bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int t,n;
int a[N][5];
int fir[N],nxt[2*N],v[N],cnt=0;
int sz;
int dfn[N],idx=0;
int tre[N];
int siz[N];
int ans[N];
int lowbit(int x){return x&(-x);}
void f2(int x,int k){
	for(int i=x;i<=n;i+=lowbit(i)){
		tre[i]+=k;
	}
}
void f1(int l,int r,int k){
	f2(l,k);
	f2(r+1,-k);
}
int f3(int r){
	int sum=0;
	for(int i=r;i;i-=lowbit(i)){
		sum+=tre[i];
	}
	return sum;
}
void add(int x,int y){
	nxt[++cnt]=fir[x];
	fir[x]=cnt;
	v[cnt]=y;
}
void dfs(int u,int fa){
	dfn[u]=++idx;
	siz[u]=1;
	for(int i=fir[u];i!=-1;i=nxt[i]){
		int to=v[i];
		if(to==fa)continue;
		dfs(to,u);
		siz[u]+=siz[to];
	}
}
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		sz=1;
		idx=0;
		cnt=0;
		for(int i=1;i<=n;i++){
			fir[i]=-1;
			tre[i]=0;
			ans[i]=0;
		}
		
		for(int i=1;i<=n;i++){
			scanf("%d%d",&a[i][1],&a[i][2]);
			if(a[i][1]==2)scanf("%d",&a[i][3]);
			if(a[i][1]==1){
				add(sz+1,a[i][2]);
				add(a[i][2],sz+1);
				sz++;
			}
		}
		dfs(1,0);
		for(int i=n;i>=1;i--){
			if(a[i][1]==2){
				f1(dfn[a[i][2]],dfn[a[i][2]]+siz[a[i][2]]-1,a[i][3]);
			}
			if(a[i][1]==1){
				ans[a[i][2]]=f3(a[i][2]);
			}
		}
		for(int i=1;i<=sz;i++){
			printf("%d ",ans[i]);
		}
		printf("\n");
	}

	return 0;
}

我做法想先求出dfs序,然后逆序用树状数组重新输入,输入为1则用树状数组确定答案,为2则修改树状数组。

2024/10/3 11:29
加载中...