1,2,最后一个过了,其他re,求调
查看原帖
1,2,最后一个过了,其他re,求调
1766406
yra_god楼主2025/8/3 11:06
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<iostream>
#include<cmath>
#include<random>
#define MAX_SIZE 1000007
#define HASH_SIZE 4000
#define INT_MIN -9999999
#define INT_MAX 99999999
#define HASHMOD 47
using namespace std;
int fa[MAX_SIZE];
int top[MAX_SIZE];
int son[MAX_SIZE];
int dfn[MAX_SIZE];
int seg[MAX_SIZE];
int size_[MAX_SIZE];
long long MOD;
int dfnnum = 0;
int weight[MAX_SIZE];
long long addL[MAX_SIZE<<1];
long long sum[MAX_SIZE<<1];
int deep[MAX_SIZE];
int head[MAX_SIZE];
int to[MAX_SIZE];
int next_[MAX_SIZE];
int cnt = 1;
void addedge(int u, int v) {
	next_[cnt] = head[u];
	to[cnt] = v;
	head[u] = cnt++;
}
void build(int n) {
	cnt = 1;
	for (int i = 1;i <= n;i++) {
		head[i] = 0;
	}
}
void up(int i) {
	sum[i] = (sum[i << 1] + sum[i << 1 | 1])%MOD;
}

void buildTree(int l,int r,int i) {
	if (l == r) {
		sum[i] = weight[seg[l]]%MOD;
	}
	else {
		int mid = (l + r) >> 1;
		buildTree(l, mid, i << 1);
		buildTree(mid + 1, r, i << 1 | 1);
		up(i);
	}
}

void dfs1(int u, int f) {
	fa[u] = f;
	size_[u] = 1;
	deep[u] = deep[f] + 1;
	for (int e = head[u];e > 0;e = next_[e]) {
		int v = to[e];
		if (v != f) {
		dfs1(v, u);
		}
	}
	for (int e = head[u];e > 0;e = next_[e]) {
		int v = to[e];
		if (v != f) {
			size_[u] += size_[v];
			if (son[u] == 0 || size_[son[u]] < size_[v]) {
				son[u] = v;
			}
		}
	}
}
void dfs2(int u,int t) {
	top[u] = t;
	dfn[u] = ++dfnnum;
	seg[dfnnum] = u;
	if (son[u] == 0)return;
	dfs2(son[u], t);
	for (int e = head[u];e > 0;e = next_[e]) {
		int v = to[e];
		if (v != fa[u]) {
			if (v != son[u]) {
				dfs2(v, v);
			}
		}
	}
}

void lazy(int n ,int i, int v) {
	sum[i] = (sum[i]+v * n)%MOD;
	addL[i] = (addL[i]+v)%MOD;
}
void down(int i, int ln, int rn) {
	if (addL[i] != 0) {
		lazy(ln,i<<1,addL[i]);
		lazy(rn, i << 1 | 1, addL[i]);
		addL[i] = 0;
	}
}
void addT(int jobl, int jobr, int l, int r,int i, int v) {
	if (jobl<=l&&jobr>=r) {
		lazy(r-l+1, i, v);
	}
	else {
		int mid = (l + r) >> 1;
		down(i, mid - l+1, r - mid);
		if (jobl<=mid) {
			addT(jobl, jobr, l, mid, i << 1,v);
		}
		if(jobr>mid) {
			addT(jobl, jobr, mid + 1, r, i << 1|1, v);
		}
	up(i);
	}
}
void Addall(int x, int y, int z,int n) {
	while (top[x]!=top[y]) {
		if (deep[x] >= deep[y]) {
			addT(dfn[top[x]], dfn[x], 1, n,1, z);
			x = fa[top[x]];
		}
		else {
			addT(dfn[top[y]], dfn[y], 1, n,1, z);
			y = fa[top[y]];
		}
	}
	int l = std::min(dfn[x], dfn[y]);
	int r = std::max(dfn[x], dfn[y]);
	addT(l, r, 1, n,1, z);
}

long long query(int jobl, int jobr, int l, int r, int i) {
	if (jobl <= l && jobr >= r) {
		return sum[i];
	}
		long long ans = 0;
		int mid = (l + r) >> 1;
		down(i, mid - l + 1, r - mid);
		if (jobl<=mid) {
			ans=(ans+query(jobl, jobr, l, mid, i << 1))%MOD;
		}
		if (jobr >mid) {
			ans = (ans+query(jobl, jobr, mid + 1, r, i << 1 | 1))%MOD;
		}
	return ans;

}
long long queryall(int x, int y, int n) {
	long long ans = 0;
	while (top[x] != top[y]) {
		if (deep[x] >= deep[y]) {
			ans = (ans+query(dfn[top[x]],dfn[x],1,n,1))%MOD;
			x = fa[top[x]];
		}
		else {
			ans = (ans+query(dfn[top[y]],dfn[y],1,n,1))%MOD;
			y = fa[top[y]];
		}
	}
	ans = (ans+query(min(dfn[x], dfn[y]), max(dfn[x], dfn[y]), 1, n, 1))%MOD;
	return ans;
}
int main() {
	int N, M, R;
    long long P;
	cin >> N;
	cin >> M;
	cin >> R;
	cin >> P;
	build(N);
	for (int i = 1;i <= N;i++) {
		scanf("%d", &weight[i]);
	}
	for (int i = 0;i < N-1;i++) {
		int u, v;
		cin >> u >> v;
		addedge(u, v);
		addedge(v, u);
	}
	MOD = P;
	dfs1(R,0);
	dfs2(R,R);
	buildTree(1,N,1);
	for (int i = 0;i < M;i++) {
		int op;
		cin >> op;
		if (op == 1) {
			int x, y, z;
			scanf("%d%d%d", &x, &y, &z);
			Addall(x, y, z,N);
		}
		else if (op == 2) {
			int x, y;
			cin >> x >> y;
			long long ans = 0;
			ans=queryall(x, y, N);
			printf("%lld\n", ans);
		}
		else if (op == 3) {
			int x, y;
			scanf("%d%d", &x, &y);
			int jobl = dfn[x];
			int jobr = size_[x] + dfn[x]-1;
			addT(jobl,jobr,1,N,1,y);
		}
		else if (op == 4) {
			int x;
			cin >> x;
			long long ans = 0;
			int jobl = dfn[x];
			int jobr = size_[x] + dfn[x] - 1;
			printf("%lld\n", query(jobl, jobr, 1, N, 1));
		}
	}
	return 0;
}
2025/8/3 11:06
加载中...