过了样例,全WA,求调
查看原帖
过了样例,全WA,求调
275209
xishanmeigao楼主2023/4/11 20:08
#include<bits/stdc++.h>
#define LL long long
using namespace std;

const int N=100010;

struct SegmentTree
{
	int l,r;
	LL sum,add;
	#define l(x)  tree[x].l
	#define r(x)  tree[x].r
	#define sum(x)  tree[x].sum
	#define add(x)  tree[x].add
}tree[8*N];

int n,m,a[N];
int in[N],out[N],num[2*N],c[2*N],len[2*N],cnt;
int head[N],ver[2*N],nxt[2*N],tot;

void add_edge(int x,int y)
{
	ver[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}

void dfs(int x,int fa)
{
	in[x]=++cnt;
	num[cnt]=x;
	c[cnt]=1;
	
	for(int i=head[x]; i; i=nxt[i])
	{
		int y=ver[i];
		if(y==fa)
			continue;
		
		dfs(y,x);
	}
	
	out[x]=++cnt;
	num[cnt]=x; 
	c[cnt]=-1;
}

void build(int p,int l,int r)
{
	l(p)=l;  r(p)=r;
	if(l==r)
	{
		sum(p)=1LL*c[l]*a[num[l]];
		return;
	}
	
	int mid=(l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	 
	sum(p)=sum(p*2)+sum(p*2+1);
}

void spread(int p)
{
	if(add(p))
	{
		sum(p*2)+=1LL*add(p)*(len[r(p*2)]-len[l(p*2)-1]);
		sum(p*2+1)+=1LL*add(p)*(len[r(p*2+1)]-len[l(p*2+1)-1]);
		add(p*2)+=add(p);
		add(p*2+1)+=add(p);
		add(p)=0;
	}
}

void change1(int p,int x,int v)
{
	if(l(p)==r(p))
	{
		sum(p)+=(LL)v;
		return;
	}
	
	int mid=(l(p)+r(p))>>1;
	if(x<=mid)
		change1(p*2,x,v);
	else
		change1(p*2+1,x,v);
	
	sum(p)=sum(p*2)+sum(p*2+1);
}

void change2(int p,int l,int r,int d)
{
	if(l<=l(p) && r>=r(p))
	{
		sum(p)+=1LL*d*(len[r(p)]-len[l(p)-1]);
		add(p)+=(LL)d;
		return;
	}
	
	spread(p);
	
	int mid=(l(p)+r(p))>>1;
	if(l<=mid)
		change2(p*2,l,r,d);
	if(r>mid)
		change2(p*2+1,l,r,d);
	
	sum(p)=sum(p*2)+sum(p*2+1);
}

LL ask(int p,int l,int r)
{
	if(l<=l(p) && r>=r(p))
		return sum(p);
		
	spread(p);
	
	int mid=(l(p)+r(p))>>1;
	LL val=0;
	if(l<=mid)
		val+=ask(p*2,l,r);
	if(r>mid)
		val+=ask(p*2+1,l,r);
	
	return val;
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++)
		scanf("%d",&a[i]);
	for(int i=1; i<n; i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add_edge(x,y); add_edge(y,x); 
	}
	
	dfs(1,0);
	for(int i=1; i<=2*n; i++)
		len[i]=len[i-1]+c[i];
		
	build(1,1,2*n);
	
	for(int i=1; i<=m; i++)
	{
		int op,x,c;
		scanf("%d",&op);
		
		switch (op)
		{
			case 1:
				scanf("%d%d",&x,&c);
				change1(1,in[x],c);
				change1(1,out[x],-c);
				break;
			case 2:
				scanf("%d%d",&x,&c);
				change2(1,in[x],out[x],c);
				break;
			default:
				scanf("%d",&x);
				printf("%lld\n",ask(1,1,in[x]));
		}
	}

	return 0;
}
2023/4/11 20:08
加载中...