我是 RE 仙人 10pts求调
查看原帖
我是 RE 仙人 10pts求调
667558
_Kamisato_Ayaka_楼主2024/11/25 14:35

只有最后一个点 A 了

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 33;

inline int read()
{
	int f = 1,res = 0;
	char ch = getchar();
	while(!isdigit(ch)){if(ch == '-') f = -1;ch = getchar();}
	while(isdigit(ch)){res = (res << 1) + (res << 3) + (ch ^ 48);ch = getchar();}
	return res * f;
}

vector <int> tree[MAXN];
int n,m,root,p,ind;
int depth[MAXN],dfn[MAXN],son[MAXN],siz[MAXN],arr[MAXN],newarr[MAXN],top[MAXN],fath[MAXN];

void dfs1(int u,int fa)
{
	depth[u] = depth[fa] + 1;
	fath[u] = fa;
	siz[u] = 1;
	int hson = -33;
	for(int i = 0;i < tree[u].size();i ++)
	{
		int v = tree[u][i];
		if(v == fa) continue;
		dfs1(v,u);
		siz[u] += siz[v];
		if(siz[v] > hson)
		{
			son[u] = v;
			hson = siz[v];
		}
	}
}

void dfs2(int u,int xtop)
{
	dfn[u] = ++ ind;
	newarr[ind] = arr[u];
	top[u] = xtop;
	if(!son[u]) return;
	dfs2(son[u],xtop);
	for(int i = 0;i < tree[u].size();i ++)
	{
		int v = tree[u][i];
		if(v == fath[u] || v == son[u]) continue;
		dfs2(v,v);
	}
}

struct node{
	int l,r,lazy,val,len;
}tr[MAXN << 2];

void pushup(int rt){tr[rt].val = (tr[rt << 1].val + tr[rt << 1 | 1].val) % p;}

void pushdown(int rt)
{
	if(tr[rt].lazy)
	{
		tr[rt << 1].val = (tr[rt << 1].val + tr[rt].lazy * tr[rt << 1].len) % p;
		tr[rt << 1 | 1].val = (tr[rt << 1 | 1].val + tr[rt].lazy * tr[rt << 1 | 1].len) % p;
		tr[rt << 1].lazy = (tr[rt << 1].lazy + tr[rt].lazy) % p;
		tr[rt << 1 | 1].lazy = (tr[rt << 1 | 1].lazy + tr[rt].lazy) % p;
		tr[rt].lazy = 0;
	}
}
void build(int l,int r,int rt)
{
	tr[rt].l = l,tr[rt].r = r;
	tr[rt].len = r - l + 1;
	if(l == r)
	{
		tr[rt].val = newarr[l] % p;
		return;
	}
	int mid = l + r >> 1;
	build(l,mid,rt << 1);
	build(mid + 1,r,rt << 1 | 1);
	pushup(rt);
}
void update(int ql,int qr,int k,int rt)
{
	int l = tr[rt].l,r = tr[rt].r;
	if(ql <= l && qr >= r)
	{
		tr[rt].val = (tr[rt].val + tr[rt].len * k) % p;
		tr[rt].lazy = (tr[rt].lazy + k) % p;
		return;
	}
	pushdown(rt);
	int mid = l + r >> 1;
	if(ql <= mid)
		update(ql,qr,k,rt << 1);
	if(qr > mid)
		update(ql,qr,k,rt << 1 | 1);
	pushup(rt);
}
int query(int ql,int qr,int rt)
{
	int l = tr[rt].l,r = tr[rt].r,ret = 0;
	if(ql <= l && qr >= r)
		return tr[rt].val;
	int mid = l + r >> 1;
	pushdown(rt);
	if(ql <= mid)
		ret = (ret + query(ql,qr,rt << 1)) % p;
	if(qr > mid)
		ret = (ret + query(ql,qr,rt << 1 | 1)) % p;
	return ret;
}
int Xupdate(int x,int y,int k)
{
	k %= p;
	while(top[x] != top[y])
	{
		if(depth[top[x]] < depth[top[y]]) swap(x,y);
		update(dfn[top[x]],dfn[x],k,1);
		x = fath[top[x]];
	}
	if(depth[x] > depth[y]) swap(x,y);
	update(dfn[x],dfn[y],k,1);
}
int Xquery(int x,int y)
{
	int ret = 0;
	while(top[x] != top[y])
	{
		if(depth[top[x]] < depth[top[y]]) swap(x,y);
		ret = (ret + query(dfn[top[x]],dfn[x],1)) % p;
		x = fath[top[x]];
	}
	if(depth[x] > depth[y]) swap(x,y);
	return ((ret + query(dfn[x],dfn[y],1)) % p);
}

signed main()
{
	n = read(),m = read(),root = read(),p = read();
	for(int i = 1;i <= n;i ++) arr[i] = read();
	for(int i = 1;i < n;i ++)
	{
		int u,v;
		u = read(),v = read();
		tree[u].push_back(v);
		tree[v].push_back(u);
	}
	depth[0] = 1;
	dfs1(root,0);
	dfs2(root,root);
	build(1,n,1);
	for(int i = 1;i <= m;i ++)
	{
		int opt,x,y,z;
		opt = read();
		if(opt == 1)
		{
			x = read(),y = read(),z = read();
			Xupdate(x,y,z);
		}
		if(opt == 2)
		{
			x = read(),y = read();
			printf("%d\n",Xquery(x,y) % p);
		}
		if(opt == 3)
		{
			x = read(),z = read();
			update(dfn[x],dfn[x] + siz[x] - 1,z,1);
		}
		if(opt == 4)
		{
			x = read();
			printf("%d\n",query(dfn[x],dfn[x] + siz[x] - 1,1) % p);
		}
	}
	return 0;
}
2024/11/25 14:35
加载中...