人已经傻了 30分 WA 求助
查看原帖
人已经傻了 30分 WA 求助
300137
风软一江水、楼主2021/10/8 20:58
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

const int N = 1e5 + 10;

int ls(int now) {
	return now << 1;
}

int rs(int now) {
	return now << 1 | 1;
}

int n,m,ro,p,a[N],w[N],tag[N * 4],t[N * 4];
int son[N],top[N],siz[N],f[N],dep[N],cnt,dfn[N];
int l[N * 4],r[N * 4];
vector <int> G[N];

void dfs1(int now,int fa) {
	dep[now] = dep[fa] + 1;
	f[now] = fa;
	siz[now] = 1;
	dfn[now] = ++ cnt;
	for(int i=0 ; i<G[now].size() ; i++) {
		int y = G[now][i];
		if(y == fa) continue;
		dfs1(y,now);
		siz[now] += siz[y];
		if(siz[y] > siz[son[now]]) son[now] = y;
	}
}

void dfs2(int now,int tp) {
	if(son[now]) dfs2(son[now],tp);
	top[now] = tp;
	for(int i=0 ; i<G[now].size() ; i++) {
		int y = G[now][i];
		if(y == f[now] || y == son[now]) continue;
		dfs2(y,y);
	}
}

void pushup(int now) {
	t[now] = (t[ls(now)] + t[rs(now)]) % p;
}

void pushdown(int now) {
	if(l[now] == r[now]) return ;
	tag[ls(now)] += tag[now] % p;
	tag[rs(now)] += tag[now] % p;
	t[ls(now)] = (t[ls(now)] + 1ll * tag[now] % p * (r[ls(now)] - l[ls(now)] + 1) % p + p) % p;
	t[rs(now)] = (t[rs(now)] + 1ll * tag[now] % p * (r[rs(now)] - l[rs(now)] + 1) % p+ p) % p;
	tag[now] = 0;
}

void build(int now,int left,int right) {
	tag[now] = 0,l[now] = left,r[now] = right;
	if(left == right) {
		t[now] = w[left] % p;
		return ;
	}
	int mid = (left + right) / 2;
	build(ls(now),left,mid);
	build(rs(now),mid + 1,right);
	pushup(now);
}

void add(int now,int left,int right,int val) {
	if(l[now] == r[now]) {
		t[now] = (t[now] % p + val % p + p) % p;
		return ;
	}
	if(tag[now]) pushdown(now);
	if(left <= l[now] && right >= r[now]) {
		t[now] = (t[now] + 1ll * val * (r[now] - l[now] + 1) % p + p) % p;
		tag[now] += val % p;
		return ;
	}
	if(left <= r[ls(now)]) add(ls(now),left,right,val);
	if(right >= l[rs(now)]) add(rs(now),left,right,val);
	pushup(now);
}

int ask(int now,int left,int right) {
	if(l[now] == r[now]) return t[now] % p;
	if(tag[now]) pushdown(now);
	if(left <= l[now] && right >= r[now]) return t[now] % p;
	long long ans = 0;
	if(left <= r[ls(now)]) ans = (ans + 1ll * ask(ls(now),left,right) % p + p) % p;
	if(right >= l[rs(now)]) ans = (ans + 1ll * ask(rs(now),left,right) % p+ p) % p;
	return (int)ans % p;
}

void add_son(int x,int val) {
	add(1,dfn[x],dfn[x] + siz[x] - 1,val);
}

int ask_son(int x) {
	return ask(1,dfn[x],dfn[x] + siz[x] - 1) % p;
}

void add_range(int x,int y,int val) {
	val %= p;
	while(top[x] != top[y]) {
		if(dep[top[x]] < dep[top[y]]) swap(x,y);
		add(1,dfn[top[x]],dfn[x],val);
		x = f[top[x]];
	}
	if(dep[x] > dep[y]) swap(x,y);
	add(1,dfn[x],dfn[y],val);
}

int ask_range(int x,int y) {
	int ans = 0;
	while(top[x] != top[y]) {
		if(dep[top[x]] < dep[top[y]]) swap(x,y);
		ans = (ans + ask(1,dfn[top[x]],dfn[x]) + p) % p;
		x = f[top[x]];
	}
	if(dep[x] > dep[y]) swap(x,y);
	ans = (ans + ask(1,dfn[x],dfn[y]) + p) % p;
	return ans % p;
}

int main() {
	scanf("%d%d%d%d",&n,&m,&ro,&p);
	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);
		G[x].push_back(y);
		G[y].push_back(x);
	}
	dfs1(ro,0);
	dfs2(ro,ro);
	for(int i=1 ; i<=n ; i++) w[dfn[i]] = a[i] % p;
	build(1,1,n);
	for(int i=1 ; i<=m ; i++) {
		int opt,x,y,z;
		scanf("%d",&opt);
		if(opt == 1) {
			scanf("%d%d%d",&x,&y,&z);
			z %= p;
			add_range(x,y,z);
		}
		else if(opt == 2) {
			scanf("%d%d",&x,&y);
			printf("%d\n",ask_range(x,y));
		}
		else if(opt == 3) {
			scanf("%d%d",&x,&z);
			z %= p;
			add_son(x,z);
		}
		else {
			scanf("%d",&x);
			printf("%d\n",ask_son(x));
		}
	}
	return 0;
}
2021/10/8 20:58
加载中...