20pts求助
查看原帖
20pts求助
252551
Xqbk楼主2021/5/13 19:38
#include<iostream>
#include<vector>
using namespace std;
const int MAXN=1234567;
long long n,m,r,p,cnt;
long long op,x,y,z;
vector<int> G[MAXN];
long long a[MAXN],f[MAXN],d[MAXN],sz[MAXN],hs[MAXN],tp[MAXN],dfn[MAXN],rk[MAXN],vis[MAXN],bt[MAXN],t[4*MAXN],tag[4*MAXN];
void pushup(int id)
{
	t[id]=t[id*2]+t[id*2+1];
	t[id]%=p;
}
void fc(int id,int l,int r,long long k)
{
	t[id]+=(r-l+1)*k;
	t[id]%=p;
	tag[id]+=k;
	tag[id]%=p;
}
void pushdown(int id,int l,int r)
{
	int mid=(l+r)/2;
	fc(id*2,l,mid,tag[id]);
	fc(id*2+1,mid+1,r,tag[id]);
	tag[id]=0;
}
void build_tree(int id,int l,int r)
{
	if(l==r)
	{
		t[id]=a[rk[l]];
		return;
	}
	int mid=(l+r)/2;
	build_tree(id*2,l,mid);
	build_tree(id*2+1,mid+1,r);
	pushup(id);
}
void update(int id,int l,int r,int x,int y,long long k)
{
	if(x<=l&&r<=y)
	{
		fc(id,l,r,k);
		return;
	}
	pushdown(id,l,r);
	int mid=(l+r)/2;
	if(x<=mid)
	{
		update(id*2,l,mid,x,y,k);
	}
	if(y>mid)
	{
		update(id*2+1,mid+1,r,x,y,k);
	}
	pushup(id);
}
long long query(int id,int l,int r,int x,int y)
{
	if(x<=l&&r<=y)
	{
		return t[id]%p;
	}
	pushdown(id,l,r);
	int mid=(l+r)/2;
	long long ans=0;
	if(x<=mid)
	{
		ans+=query(id*2,l,mid,x,y);
		ans%=p;
	}
	if(y>mid)
	{
		ans+=query(id*2+1,mid+1,r,x,y);
		ans%=p;
	}
	return ans;
}
void upd(int x,int y,long long k)
{
	update(1,1,n,x,y,k);
}
long long qry(int x,int y)
{
	return query(1,1,n,x,y);
}
long long build(int u,int dep)
{
	int hsz=0;
	hs[u]=0;
	d[u]=dep;
	sz[u]=1;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i];
		if(vis[v])
		{
			continue;
		}
		vis[v]=1;
		sz[u]+=build(v,dep+1);
		f[v]=u;
		if(sz[v]>hsz)
		{
			hs[u]=v;
			hsz=sz[v];
		}
	}
	return sz[u];
}
void dfs(int u,int top)
{
	tp[u]=top;
	cnt++;
	dfn[u]=cnt;
	rk[cnt]=u;
	bt[u]=dfn[u];
	if(hs[u])
	{
		if(!vis[hs[u]])
		{
			vis[hs[u]]=1;
			dfs(hs[u],top);
		}
		for(int i=0;i<G[u].size();i++)
		{
			int v=G[u][i];
			if(vis[v])
			{
				continue;
			}
			vis[v]=1;
			if(v!=hs[u])
			{
				dfs(v,v);
			}
			bt[u]=max(bt[u],bt[v]);
		}
	}
}
void path_add(int u,int v,int k)
{
	while(tp[u]!=tp[v])
	{
		if(d[tp[u]]<d[tp[v]])
		{
			swap(u,v);
		}
		upd(dfn[u],dfn[tp[u]],k);
		u=f[tp[u]];
	}
	upd(dfn[u],dfn[v],k);
}
long long path_sum(int u,int v)
{
	long long ans=0;
	while(tp[u]!=tp[v])
	{
		if(d[tp[u]]<d[tp[v]])
		{
			swap(u,v);
		}
		ans+=qry(dfn[u],dfn[tp[u]])%p;
		u=f[tp[u]];
	}
	ans+=qry(dfn[u],dfn[v])%p;
	return ans%p;
}
int main()
{
	//freopen("in.txt","r",stdin);
	cin>>n>>m>>r>>p;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		a[i]%=p;
	}
	for(int i=1;i<n;i++)
	{
		cin>>x>>y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	vis[r]=1;
	build(r,1);
	for(int i=1;i<=n;i++)
	{
		vis[i]=0;
	}
	vis[r]=1;
	dfs(r,r);
	build_tree(1,1,n);
	for(int i=1;i<=m;i++)
	{
		cin>>op>>x;
		if(op==1)
		{
			cin>>y>>z;
			path_add(x,y,z);
		}
		if(op==2)
		{
			cin>>y;
			cout<<path_sum(x,y)<<"\n";
		}
		if(op==3)
		{
			cin>>z;
			upd(dfn[x],dfn[x]+sz[x]-1,z);
		}
		if(op==4)
		{
			cout<<qry(dfn[x],dfn[x]+sz[x]-1)<<"\n";
		}
	}
	return 0;
}
2021/5/13 19:38
加载中...