RE on #1~10, AC 11求调
查看原帖
RE on #1~10, AC 11求调
852637
songtaoran楼主2025/1/19 13:34

rt,想敲一下板子,结果不会调了(

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ls (u << 1)
#define rs (u << 1 | 1)
const ll N = 1e5 + 10;
ll n, m, r, p, op, x, y, z, cnt, tot;
struct edge{
	ll to, nxt;
}e[N << 1];
struct Tree{
	ll sum, lazy;
}tr[N << 2];
ll head[N], a[N], tp[N], sz[N], dep[N], son[N], fa[N], dfn[N], rk[N];
void add(ll x, ll y){
	tr[++tot] = {y, head[x]};
	head[x] = tot;
}
void dfs1(ll u, ll pa){
	fa[u] = pa; dep[u] = dep[pa] + 1; sz[u] = 1;
	for(ll i = head[u]; i; i = e[i].nxt){
		ll v = e[i].to;
		if(v == pa) continue;
		dfs1(v, u);
		sz[u] += sz[v];
		if(sz[son[u]] < sz[v]) son[u] = v;
	}
}
void dfs2(ll u, ll tp_fa){
	dfn[u] = ++cnt; rk[cnt] = u; tp[u] = tp_fa;
	if(son[u]) dfs2(son[u], tp[u]);
	for(ll i = head[u]; i; i = e[i].nxt){
		ll v = e[i].to;
		if(v == son[u] || v == fa[u]) continue;
		dfs2(v, v);
	}
}
void pushup(ll u){
	tr[u].sum = (tr[ls].sum + tr[rs].sum) % p;
}
void pushdown(ll u, ll l, ll r){
	if(!tr[u].lazy) return;
	ll mid = (l + r) >> 1;
	tr[ls].sum = (tr[ls].sum + tr[u].lazy * (mid - l + 1) % p) % p;
	tr[rs].sum = (tr[rs].sum + tr[u].lazy * (    r - mid) % p) % p;
	tr[ls].lazy = (tr[ls].lazy + tr[u].lazy) % p;
	tr[rs].lazy = (tr[rs].lazy + tr[u].lazy) % p;
	tr[u].lazy = 0;
}
void build(ll u, ll l, ll r){
	if(l == r){
		tr[u].sum = a[rk[l]] % p;
		return;
	}
	ll mid = (l + r) >> 1;
	build(ls, l, mid); build(rs, mid + 1, r);
	pushup(u);
}
void update(ll u, ll l, ll r, ll L, ll R, ll val){
	if(L <= l && r <= R){
		tr[u].sum = (tr[u].sum + (r - l + 1) * val % p) % p;
		tr[u].lazy = (tr[u].lazy + val) % p;
		return;
	}
	pushdown(u, l, r);
	ll mid = (l + r) >> 1;
	if(L <= mid) update(ls, l, mid, L, R, val);
	if(mid < R)  update(rs, mid + 1, r, L, R, val);
	pushup(u);
}
ll query(ll u, ll l, ll r, ll L, ll R){
	if(L <= l && r <= R) return tr[u].sum % p;
	pushdown(u, l, r);
	ll mid = (l + r) >> 1, ans = 0;
	if(L <= mid) ans = (ans + query(ls, l, mid, L, R)) % p;
	if(mid < R)  ans = (ans + query(rs, mid + 1, r, L, R)) % p;
	return ans;
}
void uv_update(ll u, ll v, ll w){
	while(tp[u] != tp[v]){
		if(dep[tp[u]] < dep[tp[v]]) swap(u, v);
		update(1, 1, n, dfn[tp[u]], dfn[u], w);
		u = fa[tp[u]];
	}
	if(dep[u] < dep[v]) swap(u, v);
	update(1, 1, n, dfn[v], dfn[u], w);
}
ll uv_query(ll u, ll v){
	ll ans = 0;
	while(tp[u] != tp[v]){
		if(dep[tp[u]] < dep[tp[v]]) swap(u, v);
		ans = (ans + query(1, 1, n, dfn[tp[u]], dfn[u])) % p;
		u = fa[tp[u]];
	}
	if(dep[u] < dep[v]) swap(u, v);
	ans = (ans + query(1, 1, n, dfn[v], dfn[u])) % p;
	return ans;
}
int main(){
	cin >> n >> m >> r >> p;
	for(ll i = 1; i <= n; i++) scanf("%lld", &a[i]);
	for(ll i = 1; i <  n; i++){
		scanf("%lld %lld", &x, &y);
		add(x, y); add(y, x);
	}
	dfs1(r, 0); dfs2(r, r);
	build(1, 1, n);
	while(m--){
		scanf("%lld %lld", &op, &x);
		if(op == 1){
			scanf("%lld %lld", &y, &z);
			uv_update(x, y, z);
		}else if(op == 2){
			scanf("%lld", &y);
			printf("%lld\n", uv_query(x, y));
		}else if(op == 3){
			scanf("%lld", &y);
			update(1, 1, n, dfn[x], dfn[x] + sz[x] - 1, y);
		}else printf("%lld\n", query(1, 1, n, dfn[x], dfn[x] + sz[x] - 1));
	}
	return 0;
}
2025/1/19 13:34
加载中...