标签:root wap build push markdown == \n lld date
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
const int N = 1e5 + 10;
int n,m,root,mod,cnt,a[N],father[N],deep[N],size[N],son[N],rk[N],top[N],id[N];
struct Edge {
int Next, to;
}e[N<<1];
int head[N], num;
void add(int from, int to) {
e[++num].Next = head[from];
e[num].to = to;
head[from] = num;
}
struct Segment_Tree
{
ll ans[N<<2], tag[N<<2];
inline ll ls(ll p) { return p << 1; }
inline ll rs(ll p) { return p << 1 | 1; }
inline void pushup(ll p) {
ans[p] = (ans[ls(p)] + ans[rs(p)]) % mod;
}
inline void pushdown(ll p, ll l, ll r) {
ll mid = (l + r) >> 1;
ans[ls(p)] += (mid - l + 1) * tag[p] % mod;
tag[ls(p)] += tag[p] % mod;
ans[rs(p)] += (r - mid) * tag[p] % mod;
tag[rs(p)] += tag[p] % mod;
tag[p] = 0;
}
void build(ll p, ll l, ll r) {
if(l == r) {
ans[p] = a[rk[l]];
return;
}
ll mid = (l + r) >> 1;
build(ls(p), l, mid);
build(rs(p), mid + 1, r);
pushup(p);
}
void update(ll p, ll l, ll r, ll ul, ll ur, ll k) {
if(ul <= l && r <= ur) {
ans[p] += (r - l + 1) * k % mod;
tag[p] += k % mod;
return;
}
if(tag[p]) pushdown(p, l, r);
ll mid = (l + r) >> 1;
if(ul <= mid) update(ls(p), l, mid, ul, ur, k);
if(ur > mid) update(rs(p), mid + 1, r, ul, ur, k);
pushup(p);
}
ll query(ll p, ll l, ll r, ll ql, ll qr) {
if(ql <= l && r <= qr)
return ans[p];
if(tag[p]) pushdown(p, l, r);
ll mid = (l + r) >> 1, res = 0;
if(ql <= mid) res = (res + query(ls(p), l, mid, ql, qr)) % mod;
if(qr > mid) res = (res + query(rs(p), mid + 1, r, ql, qr)) % mod;
return res % mod;
}
}T;
struct lianpou
{
void dfs1(int u, int f, int depth)
{
father[u] = f;
deep[u] = depth;
size[u] = 1;
for(int i = head[u]; i; i = e[i].Next)
{
int v = e[i].to;
if(v == f) continue;
dfs1(v, u, depth + 1);
size[u] += size[v];
if(size[v] > size[son[u]])
son[u] = v;
}
}
void dfs2(int u, int tp)
{
top[u] = tp;
id[u] = ++cnt;
rk[cnt] = u;
if(!son[u]) return;
dfs2(son[u], tp);
for(int i = head[u]; i; i = e[i].Next)
{
int v = e[i].to;
if(v != son[u] && v != father[u])
dfs2(v, v);
}
}
ll sum(int x, int y)
{
ll ans = 0;
int fx = top[x], fy = top[y];
while(fx != fy)
{
if(deep[fx] >= deep[fy]) {
ans = (ans + T.query(1, 1, n, id[fx], id[x])) % mod;
x = father[fx], fx = top[x];
}
else {
ans = (ans + T.query(1, 1, n, id[fy], id[y])) % mod;
y = father[fy], fy = top[y];
}
}
if(id[x] > id[y]) swap(x, y);
ans = (ans + T.query(1, 1, n, id[x], id[y])) % mod;
return ans % mod;
}
void update(int x, int y, int z)
{
int fx = top[x], fy = top[y];
while(fx != fy)
{
if(deep[fx] >= deep[fy]) {
T.update(1, 1, n, id[fx], id[x], z);
x = father[fx], fx = top[x];
}
else
{
T.update(1, 1, n, id[fy], id[y], z);
y = father[fy], fy = top[y];
}
}
if(id[x] > id[y]) swap(x, y);
T.update(1, 1, n, id[x], id[y], z);
}
}L;
int main()
{
scanf("%d%d%d%d", &n, &m, &root, &mod);
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
for(int i = 1, u, v; i < n; i++)
{
scanf("%d%d", &u, &v);
add(u,v); add(v,u);
}
L.dfs1(root, 0, 1);
L.dfs2(root, root);
T.build(1, 1, n);
for(int i = 1, opt, x, y, z; i <= m; i++)
{
scanf("%d", &opt);
if(opt == 1)
{
scanf("%d%d%d", &x, &y, &z);
L.update(x, y, z);
}
else if(opt == 2)
{
scanf("%d%d", &x, &y);
printf("%lld\n", L.sum(x, y));
}
else if(opt == 3)
{
scanf("%d%d", &x, &z);
T.update(1, 1, n, id[x], id[x] + size[x] - 1, z);
}
else if(opt == 4)
{
scanf("%d", &x);
printf("%lld\n", T.query(1, 1, n, id[x], id[x] + size[x] - 1));
}
}
return 0;
}
标签:root wap build push markdown == \n lld date
原文地址:https://www.cnblogs.com/colorfulmist/p/10151732.html