_Kamisato_Ayaka_ @ 2024-11-25 14:35:58
只有最后一个点 A 了
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 33;
inline int read()
{
int f = 1,res = 0;
char ch = getchar();
while(!isdigit(ch)){if(ch == '-') f = -1;ch = getchar();}
while(isdigit(ch)){res = (res << 1) + (res << 3) + (ch ^ 48);ch = getchar();}
return res * f;
}
vector <int> tree[MAXN];
int n,m,root,p,ind;
int depth[MAXN],dfn[MAXN],son[MAXN],siz[MAXN],arr[MAXN],newarr[MAXN],top[MAXN],fath[MAXN];
void dfs1(int u,int fa)
{
depth[u] = depth[fa] + 1;
fath[u] = fa;
siz[u] = 1;
int hson = -33;
for(int i = 0;i < tree[u].size();i ++)
{
int v = tree[u][i];
if(v == fa) continue;
dfs1(v,u);
siz[u] += siz[v];
if(siz[v] > hson)
{
son[u] = v;
hson = siz[v];
}
}
}
void dfs2(int u,int xtop)
{
dfn[u] = ++ ind;
newarr[ind] = arr[u];
top[u] = xtop;
if(!son[u]) return;
dfs2(son[u],xtop);
for(int i = 0;i < tree[u].size();i ++)
{
int v = tree[u][i];
if(v == fath[u] || v == son[u]) continue;
dfs2(v,v);
}
}
struct node{
int l,r,lazy,val,len;
}tr[MAXN << 2];
void pushup(int rt){tr[rt].val = (tr[rt << 1].val + tr[rt << 1 | 1].val) % p;}
void pushdown(int rt)
{
if(tr[rt].lazy)
{
tr[rt << 1].val = (tr[rt << 1].val + tr[rt].lazy * tr[rt << 1].len) % p;
tr[rt << 1 | 1].val = (tr[rt << 1 | 1].val + tr[rt].lazy * tr[rt << 1 | 1].len) % p;
tr[rt << 1].lazy = (tr[rt << 1].lazy + tr[rt].lazy) % p;
tr[rt << 1 | 1].lazy = (tr[rt << 1 | 1].lazy + tr[rt].lazy) % p;
tr[rt].lazy = 0;
}
}
void build(int l,int r,int rt)
{
tr[rt].l = l,tr[rt].r = r;
tr[rt].len = r - l + 1;
if(l == r)
{
tr[rt].val = newarr[l] % p;
return;
}
int mid = l + r >> 1;
build(l,mid,rt << 1);
build(mid + 1,r,rt << 1 | 1);
pushup(rt);
}
void update(int ql,int qr,int k,int rt)
{
int l = tr[rt].l,r = tr[rt].r;
if(ql <= l && qr >= r)
{
tr[rt].val = (tr[rt].val + tr[rt].len * k) % p;
tr[rt].lazy = (tr[rt].lazy + k) % p;
return;
}
pushdown(rt);
int mid = l + r >> 1;
if(ql <= mid)
update(ql,qr,k,rt << 1);
if(qr > mid)
update(ql,qr,k,rt << 1 | 1);
pushup(rt);
}
int query(int ql,int qr,int rt)
{
int l = tr[rt].l,r = tr[rt].r,ret = 0;
if(ql <= l && qr >= r)
return tr[rt].val;
int mid = l + r >> 1;
pushdown(rt);
if(ql <= mid)
ret = (ret + query(ql,qr,rt << 1)) % p;
if(qr > mid)
ret = (ret + query(ql,qr,rt << 1 | 1)) % p;
return ret;
}
int Xupdate(int x,int y,int k)
{
k %= p;
while(top[x] != top[y])
{
if(depth[top[x]] < depth[top[y]]) swap(x,y);
update(dfn[top[x]],dfn[x],k,1);
x = fath[top[x]];
}
if(depth[x] > depth[y]) swap(x,y);
update(dfn[x],dfn[y],k,1);
}
int Xquery(int x,int y)
{
int ret = 0;
while(top[x] != top[y])
{
if(depth[top[x]] < depth[top[y]]) swap(x,y);
ret = (ret + query(dfn[top[x]],dfn[x],1)) % p;
x = fath[top[x]];
}
if(depth[x] > depth[y]) swap(x,y);
return ((ret + query(dfn[x],dfn[y],1)) % p);
}
signed main()
{
n = read(),m = read(),root = read(),p = read();
for(int i = 1;i <= n;i ++) arr[i] = read();
for(int i = 1;i < n;i ++)
{
int u,v;
u = read(),v = read();
tree[u].push_back(v);
tree[v].push_back(u);
}
depth[0] = 1;
dfs1(root,0);
dfs2(root,root);
build(1,n,1);
for(int i = 1;i <= m;i ++)
{
int opt,x,y,z;
opt = read();
if(opt == 1)
{
x = read(),y = read(),z = read();
Xupdate(x,y,z);
}
if(opt == 2)
{
x = read(),y = read();
printf("%d\n",Xquery(x,y) % p);
}
if(opt == 3)
{
x = read(),z = read();
update(dfn[x],dfn[x] + siz[x] - 1,z,1);
}
if(opt == 4)
{
x = read();
printf("%d\n",query(dfn[x],dfn[x] + siz[x] - 1,1) % p);
}
}
return 0;
}
by _Kamisato_Ayaka_ @ 2024-11-25 14:56:07
已 AC,此帖结
by cengzh @ 2024-11-27 18:49:52
大师还在吗,是怎么调的,俺也错了@_KamisatoAyaka
by _Kamisato_Ayaka_ @ 2024-11-27 19:01:15
@cengzh
int Xupdate(int x,int y,int k)
{
k %= p;
while(top[x] != top[y])
{
if(depth[top[x]] < depth[top[y]]) swap(x,y);
update(dfn[top[x]],dfn[x],k,1);
x = fath[top[x]];
}
if(depth[x] > depth[y]) swap(x,y);
update(dfn[x],dfn[y],k,1);
}
这个东西返回值类型应该是 void ,我打错了
by cengzh @ 2024-11-27 19:06:34
呜呜不是这个问题,不过还是thx