求调,Ac on#11,其他全re
查看原帖
求调,Ac on#11,其他全re
1210321
zhangzhixu000001楼主2024/6/26 16:44
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
struct sgmgent_tree{
	int l,r;
	int sum, tag;
}tr[maxn<<2];
int mod;
vector<int> e[maxn];
int ls(int p){return p<<1;}
int rs(int p){return p<<1|1;}
void up(int p){tr[p].sum=(tr[ls(p)].sum+tr[rs(p)].sum)%mod;}
void addtag(int p,int d){tr[p].tag+=d;tr[p].sum+=(d*(tr[p].r-tr[p].l+1))%mod;}
void pushdown(int n)
{
	if(tr[n].tag)
	{
		addtag(ls(n),tr[n].tag);
		addtag(rs(n),tr[n].tag);
		tr[n].tag=0;
	}
}
void addedge(int u,int v)
{
	e[u].push_back(v);
	e[v].push_back(u);
}
int n,m,root;
int point_w[maxn],point_new_w[maxn];
int son[maxn],id[maxn],top[maxn],deep[maxn],size[maxn],fa[maxn];
int num;
void dfs1(int x,int father)
{
	deep[x]=deep[father]+1;
	fa[x]=father;
	size[x]=1;
	for (int i=0;i<e[x].size();i++)
	{
		int y=e[x][i];
		if(y!=father)
		{
			fa[y]=x;
			dfs1(y,x);
			size[x]+=size[y];
			if(!son[x]||size[son[x]]<size[y]) son[x]=y;
		}
	}
}
void dfs2(int x,int topx)
{
	top[x]=topx;
	id[x]=++num;
	point_new_w[x]=point_w[x];
	if(!son[x]) return;
	dfs2(son[x],topx);
	for (int i=0;i<e[x].size();i++)
	{
		int y=e[x][i];
		if(y!=fa[x]&&y!=son[x]) dfs2(y,y);
	}
}
void build (int l,int r,int p)
{
	tr[p].l=l;tr[p].r=r;
	if(l==r)
	{
		tr[p].sum=point_new_w[l]%mod;
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,ls(p));
	build(mid+1,r,rs(p));
	up(p);
}
void update(int l,int r,int p,int d)
{
	if(l<=tr[n].l&&tr[n].r<=r){addtag(p,d);return;}
	pushdown(p);
	if(tr[ls(p)].r>=l) update(l,r,ls(p),d);
	if(tr[rs(p)].l<=r) update(l,r,rs(p),d);
	up(p);
}
int query(int l,int r,int p)
{
	if(l<=tr[p].l&&tr[p].r<=r) return tr[p].sum;
	pushdown(p);
	int tot=0;
	if(tr[ls(p)].r>=l) tot+=query(l,r,ls(p));
	if(tr[rs(p)].l<=r) tot+=query(l,r,rs(p));
	return tot%mod;
}
void update_range(int x,int y,int z)
{
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		update(id[top[x]],id[x],1,z);
		x=fa[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	update(id[x],id[y],1,z);
}
int query_range(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		ans+=query(id[top[x]],id[x],1);
		ans%=mod;
		x=fa[top[x]];
	}
	ans+=query(id[x],id[y],1);
	return ans%mod;
}
void update_tree(int x,int k){update(id[x],id[x]+size[x]-1,1,k);}
int query_tree(int x){return query(id[x],id[x]+size[x]-1,1);}
int main()
{
	ios::sync_with_stdio(0);
	cin>>n>>m>>root>>mod;
	for (int i=1;i<=n;i++) cin>>point_w[i];
	for(int i=1;i<n;i++)
	{
		int u,v;cin>>u>>v;
		addedge(u,v);
	}
	dfs1(root,0);
	dfs2(root,root);
	build(1,n,1);
	for (int i=1;i<=m;i++)
	{
		int opt,x,y,z;
		cin>>opt>>x;
		switch(opt)
		{
			case 1:cin>>y>>z;update_range(x,y,z);break;
			case 2:cin>>y;cout<<query_range(x,y)<<endl;break;
			case 3:cin>>z;update_tree(x,z);break;
			case 4:cout<<query_tree(x)<<endl;break;
			default:break;
		}
	}
 	return 0;
}
2024/6/26 16:44
加载中...