求调,re
查看原帖
求调,re
892323
AkTtt楼主2024/8/7 17:10
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>

using namespace std;
#define endl '\n'
typedef long long LL;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
const LL INFF = 0x3f3f3f3f3f3f3f3f;
// const int INF = 0x3f3f3f3f,mod = 998244353;
#define debug(x) cout<< "[debug]" #x << " = " << x <<endl

int n, m, root, mod, cnt;
int a[N], nw[N], son[N];
int fa[N], sz[N], top[N];
int id[N], dep[N];
vector<int> ve[N];
struct node{
	LL l, r;
	LL sum, tag;
}v[N * 4];

void dfs1(int x, int f){
	sz[x] = 1, fa[x] = f;
	for(auto k : ve[x]){
		if(k == f)continue;
		dep[k] = dep[x] + 1;
		dfs1(k, x);
		sz[x] += sz[k];
		if(sz[k] > sz[son[x]])son[x] = k;
	}
}

void dfs2(int x, int t){
	top[x] = t, id[x] = ++cnt, nw[cnt] = a[x];
	if(!son[x])return ;
	dfs2(son[x], t);

	for(auto k : ve[x]){
		if(k == fa[x] || k == son[x])continue;
		dfs2(k, k);
	}
}

void pushup(int u){
	v[u].sum = v[u * 2].sum + v[u * 2 + 1].sum;
	v[u].sum %= mod;
}

void build(int u, int l, int r){
	if(l == r)v[u] = {l, r, nw[l] % mod};
	else{
		v[u] = {l, r};
		int mid = (l + r) >> 1;
		build(u * 2, l, mid);
		build(u * 2 + 1, mid + 1, r);

		pushup(u);
	}
}

void settag(int u, LL k){
	v[u].sum += (v[u].r - v[u].l + 1) * k;
	v[u].sum %= mod;
	v[u].tag += k;
}

void pushdown(int u){
	if(v[u].tag){
		settag(u * 2, v[u].tag);
		settag(u * 2 + 1, v[u].tag);

		v[u].tag = 0;
	}
}

void update(int u, int l, int r, int k){
	if(v[u].l == l && v[u].r == r){
		settag(u, k);
	}
	else{
		pushdown(u);
		int mid = (v[u].l + v[u].r) >> 1;
		if(r <= mid)update(u * 2, l, r, k);
		else if(l > mid)update(u * 2 + 1, l, r, k);
		else update(u * 2, l, mid, k), update(u * 2 + 1, mid + 1, r, k);

		pushup(u);
	}
}

LL query(int u, int l, int r){
	if(v[u].l == l && v[u].r == r){
		return v[u].sum;
	}
	else{
		pushdown(u);
		int mid = (v[u].l + v[u].r) >> 1;
		if(mid >= r)return query(u * 2, l, r);
		else if(l > mid)return query(u * 2 + 1, l, r);
		else return query(u * 2, l, mid) + query(u * 2 + 1, mid + 1, r);
	}
}

int query_path(int u, int v){
	int res = 0;
	while(top[u] != top[v]){
		if(dep[top[u]] < dep[top[v]])swap(u, v);
		res += query(1, id[top[u]], id[u]);
		res %= mod;
		u = fa[top[u]];
	};

	if(dep[u] > dep[v])swap(u, v);
	res += query(1, id[u], id[v]);
	res %= mod;
	return res;
}

void update_path(int u, int v, int k){
	int cnt = 0;
	while(top[u] != top[v]){
		cnt++;
		if(dep[top[u]] < dep[top[v]])swap(u, v);
		update(1, id[top[u]], id[u], k);
		u = fa[top[u]];
		if(cnt == 1)break;
	};

	if(dep[u] > dep[v])swap(u, v);
	update(1, id[u], id[v], k);
}

void solve()
{
    cin >> n >> m >> root >> mod;
    for(int i = 1; i <= n; i++)cin >> a[i];
    for(int i = 1; i < n; i++){
    	int a, b;
    	cin >> a >> b;
    	ve[a].push_back(b);
    	ve[b].push_back(a);
    }

    dfs1(root, -1);
    dfs2(root, root);

    build(1, 1, n);

    while(m--){
    	int q;
    	cin >> q;
    	if(q == 1){
    		int x, y, z;
    		cin >> x >> y >> z;
    		update_path(x, y, z);
    	}
    	else if(q == 2){
    		int x, y;
    		cin >> x >> y;
    		cout << query_path(x, y) % mod << endl;
    	}
    	else if(q == 3){
    		int x, z;
    		cin >> x >> z;
    		update(1, id[x], id[x] + sz[x] - 1, z);
    	}
    	else {
    		int x;
    		cin >> x;
    		cout << query(1, id[x], id[x] + sz[x] - 1) % mod << endl;
    	}
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T = 1;
    // cin >> T;
    while(T--)
    {
        solve();
    }
}
2024/8/7 17:10
加载中...