30pts,AC#2#9#10,求助,已开longlong
查看原帖
30pts,AC#2#9#10,求助,已开longlong
610393
murder_drones楼主2023/1/16 15:45
#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
using namespace std;
const int maxn=1e5+10;

vector<int> son[maxn];
bool ish[maxn];//isheavy
int fa[maxn],depth[maxn],size[maxn],top[maxn],dfn[maxn],redfn[maxn],dfncnt=0;
long long val[maxn];

int hs[maxn],hv[maxn];//heavyson,heavyvalue

int n,m,r=1;

//buildtree
vector<int> to[maxn];
int grtotr_vis[maxn];

void addedge(int u,int v)
{
	to[u].push_back(v);
	to[v].push_back(u);
}

void inputs()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&val[i]);
	}
	for(int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		addedge(u,v);
	}
}

void graphtotree(int x,int dp) //dfs
{
	grtotr_vis[x]=1;
	depth[x]=dp;
	size[x]=1;
	for(int i=0;i<to[x].size();i++)
	{
		if(!grtotr_vis[to[x][i]])
		{
			int s=to[x][i];
			fa[s]=x;
			son[x].push_back(s);
			graphtotree(s,dp+1);
			size[x]+=size[s];
			if(size[s]>hv[x])
			{
				ish[hs[x]]=0;
				ish[s]=1;
				hs[x]=s;
				hv[x]=size[s];
			}
		}
	}
}

void dfs1(int x)
{
	dfn[++dfncnt]=x;
	if(ish[x])
	{
		top[x]=top[fa[x]];
	}
	else
	{
		top[x]=x;
	}
	
	if(hs[x]!=0)
	{
		dfs1(hs[x]);
		for(int i=0;i<son[x].size();i++)
		{
			if(son[x][i]!=hs[x])
			{
				dfs1(son[x][i]);
			}
		}
	}
}

//-----------------------------------------------------------------
long long a[maxn],sum_v[4*maxn],add_lazy[4*maxn];

void build(int p,int l,int r)
{
	if(l==r)
	{
		sum_v[p]=a[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	sum_v[p]=sum_v[p*2]+sum_v[p*2+1];
}
void addf(int p,int l,int r,long long v)
{
	add_lazy[p]=add_lazy[p]+v;
	sum_v[p]=sum_v[p]+v*(r-l+1);
	return ;
}
void pushdown(int p,int l,int r,int mid)
{
	if(add_lazy[p]!=0)
	{
		addf(p*2,l,mid,add_lazy[p]);
		addf(p*2+1,mid+1,r,add_lazy[p]);
		add_lazy[p]=0;
	}
}
void pluss(int p,int l,int r,int tl,int tr,long long v)
{
	if(tl<=l && r<=tr) return addf(p,l,r,v);
	
	int mid=(l+r)>>1;
	pushdown(p,l,r,mid);
	if(tl<=mid)
	{
		pluss(p*2,l,mid,tl,tr,v);
	}
	if(mid<tr)
	{
		pluss(p*2+1,mid+1,r,tl,tr,v);
	}
	sum_v[p]=sum_v[p*2]+sum_v[p*2+1];
}
long long query(int p,int l,int r,int tl,int tr)
{
	if(tl<=l && r<=tr) return sum_v[p];
	
	int mid=(l+r)>>1;
	long long ret=0;
	pushdown(p,l,r,mid);
	if(tl<=mid)
	{
		ret=ret+query(p*2,l,mid,tl,tr);
	}
	if(mid<tr)
	{
		ret=ret+query(p*2+1,mid+1,r,tl,tr);
	}
	
	return ret;
}

//-------------------------------------------------------

long long heavyquery(int x,int y)
{
	if(depth[x]>depth[y])
	{
		int t=x;x=y;y=t;
	}
	return query(1,1,n,redfn[x],redfn[y]);
}

void heavyplus(int x,int y,long long v)
{
	if(depth[x]>depth[y])
	{
		int t=x;x=y;y=t;
	}
	pluss(1,1,n,redfn[x],redfn[y],v);
//	cout<<query(1,1,n,redfn[1],redfn[1]);
//	cout<<x<<' '<<y;
}

long long pathquery(int x,int y)
{
	long long ans=0;
	while(top[x]!=top[y])
	{
//		printf("%d %d %d\n",x,y,ans);
		if(depth[top[x]]>=depth[top[y]])
		{
			ans=ans+heavyquery(top[x],x);
			x=top[x];
			if(x!=r) x=fa[x];
		}
		else
		{
			ans=ans+heavyquery(top[y],y);
			y=top[y];
			if(y!=r) y=fa[y];
		}
//		printf("%d %d %d\n",x,y,ans);
	}
	ans=ans+heavyquery(x,y);
	return ans;
}

void pathplus(int x,int y,long long v)
{
	while(top[x]!=top[y])
	{
//		printf("%d %d %d %d\n",x,y,query(1,1,n,x,x),query(1,1,n,y,y));
		if(depth[top[x]]>=depth[top[y]])
		{
			heavyplus(top[x],x,v);
			x=top[x];
			if(x!=r) x=fa[x];
		}
		else
		{
			heavyplus(top[y],y,v);
			y=top[y];
			if(y!=r) y=fa[y];
		}
//		printf("%d %d %d %d\n",x,y,query(1,1,n,x,x),query(1,1,n,y,y));
	}
	heavyplus(x,y,v);
}

long long subquery(int x)
{
	return query(1,1,n,redfn[x],redfn[x]+size[x]-1);
}

void subplus(int x,long long v)
{
	pluss(1,1,n,redfn[x],redfn[x]+size[x]-1,v);
}

int main()
{
	inputs();
	graphtotree(r,1);
	/*test graphtotree
	for(int i=1;i<=n;i++)
	{
		printf("%d ",ish[i]);
	}
	*/
	dfs1(r);
	/*test dfs1
	for(int i=1;i<=n;i++)
	{
		printf("%d ",depth[i]);
	}
	*/
	for(int i=1;i<=n;i++)
	{
		redfn[dfn[i]]=i;
		a[i]=val[dfn[i]];
	}
	/*test redfn
	for(int i=1;i<=dfncnt;i++)
	{
		printf("%d ",redfn[i]);
	}
	*/
	/*test tree
	for(int i=1;i<=dfncnt;i++)
	{
		printf("%d ",a[i]);
	}
	*/
	build(1,1,n);
//	pathplus(2,9,1);
//	subplus(3,2);
//	cout<<pathquery(5,7);
//	cout<<subquery(3);
//	cout<<"input over\n";
	for(int i=1;i<=m;i++)
	{
		int op;
		scanf("%d",&op);
//		cout<<"op is"<<op<<" ";
		if(op==1)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			
			pathplus(x,x,y);
		}
		else if(op==2)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			subplus(x,y);
		}
		else if(op==3)
		{
			int x;
			scanf("%d",&x);
			printf("%lld\n",pathquery(1,x));
//			cout<<ish[5];
		}
	}
	return 0;
}

/*
in:
5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3

ans:
6
9
13
*/
2023/1/16 15:45
加载中...