a1874658776 @ 2024-07-25 15:14:08
其余:WA
代码如下:
//#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define Mid (left+right)/2
#define Ls i<<1
#define Rs i<<1|1
#define Lson Ls,left,Mid
#define Rson Rs,Mid+1,right
#define For(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
inline int read()
{
int x = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -f; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
#define maxN 100010
ll n,rt,m,Mod,opt,x,y,z;
ll nums[maxN];//节点值
vector<ll> v[maxN];//存边
ll fa[maxN],dep[maxN],top[maxN],dfn[maxN],no[maxN],hson[maxN],siz[maxN],cnt;
// 父节点 , 深度,当前链顶端节点,线段树中编号,dfn序,重儿子编号,子树大小,dfs计数
struct node//线段树节点
{
ll l,r,sum,lazytag;
};
node tr[maxN];
void chainsplit_dfs1(ll root,ll father,ll depth)
{
siz[root]=1;
fa[root]=father;
dep[root]=depth;
if(v[root].empty()) return ;
ll sonsizemax=0;
hson[root]=0;
For(i,0,v[root].size()-1)
{
ll nownode=v[root][i];
if(nownode==father) continue;
chainsplit_dfs1(nownode,root,depth+1);
if(siz[nownode]>sonsizemax)
{
sonsizemax=siz[nownode];
hson[root]=nownode;
}
siz[root]+=siz[nownode];
}
return;
}
void chainsplit_dfs2(ll root,ll topnode)
{
++cnt;
dfn[root]=cnt;
no[cnt]=root;
top[root]=topnode;
if(siz[root]==1) return ;
chainsplit_dfs2(hson[root],topnode);
For(i,1,v[root].size()-1)
{
ll nownode=v[root][i];
if(nownode==fa[root]||nownode==hson[root]) continue;
chainsplit_dfs2(nownode,nownode);
}
return;
}
inline void push_up(ll i)
{
tr[i].sum=(tr[Ls].sum+tr[Rs].sum)%Mod;
return ;
}
inline void push_down(ll i)
{
tr[Ls].sum=(tr[Ls].sum+((tr[Ls].r-tr[Ls].l+1)*tr[i].lazytag))%Mod;
tr[Rs].sum=(tr[Rs].sum+((tr[Rs].r-tr[Rs].l+1)*tr[i].lazytag))%Mod;
tr[Ls].lazytag=(tr[Ls].lazytag+tr[i].lazytag)%Mod;
tr[Rs].lazytag=(tr[Rs].lazytag+tr[i].lazytag)%Mod;
tr[i].lazytag=0;
return ;
}
void build_segtree(ll i, ll left, ll right)//建树
{
tr[i].l = left;
tr[i].r = right;
tr[i].lazytag = 0;
if (left == right)
{
tr[i].sum = nums[no[left]]%Mod;
//cout << "build_segtree: leaf node " << i << " sum = " << tr[i].sum << endl;
return;
}
build_segtree(Lson);
build_segtree(Rson);
push_up(i);
//cout << "build_segtree: internal node " << i << " sum = " << tr[i].sum << endl;
return;
}
void update_seg(ll i, ll left, ll right, ll x)//线段树更新
{
if (tr[i].r < left || tr[i].l > right) return;
if (tr[i].l >= left && tr[i].r <= right)
{
tr[i].sum = (tr[i].sum + ((tr[i].r - tr[i].l + 1) * x) ) ;
tr[i].lazytag = (tr[i].lazytag + x) ;
//cout << "update_seg: node " << i << " updated sum = " << tr[i].sum << " lazytag = " << tr[i].lazytag << endl;
//cout<<tr[i].l<<"--------"<<tr[i].r<<endl;
return;
}
push_down(i);
if (tr[Ls].r >= left) update_seg(Ls, left, right, x);
if (tr[Rs].l <= right) update_seg(Rs, left, right, x);
push_up(i);
//cout << "update_seg: node " << i << " sum after push_up = " << tr[i].sum << endl;
return;
}
ll query_seg(ll i, ll left, ll right)//线段树查询
{
if (tr[i].r < left || tr[i].l > right) return 0;
if (tr[i].l >= left && tr[i].r <= right)
{
//cout << "query_seg: node " << i << " sum = " << tr[i].sum << endl;
return tr[i].sum%Mod;
}
push_down(i);
ll tmp = 0;
if (tr[Ls].r >= left) tmp = (tmp + query_seg(Ls, left, right))%Mod ;
if (tr[Rs].l <= right) tmp = (tmp + query_seg(Rs, left, right))%Mod ;
//cout << "query_seg: node " << i << " sum after query = " << tmp << endl;
return tmp;
}
void update1(ll u,ll v,ll x)//操作1
{
x%=Mod;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
//cout<<"update_seg: u:"<<u<<"-"<<no[u]<<" v:"<<v<<"-"<<no[v]<<endl;
update_seg(1,dfn[top[u]],dfn[u],x);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
update_seg(1,dfn[v],dfn[u],x);
return ;
}
void update2(ll root,ll x)//操作3
{
x%=Mod;
update_seg(1,dfn[root],dfn[root]+siz[root]-1,x);
return ;
}
ll query1(ll u,ll v)//操作2
{
ll ans=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans=(ans+query_seg(1,dfn[top[u]],dfn[u]))%Mod;
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
ans=(ans+query_seg(1,dfn[v],dfn[u]))%Mod;
return ans;
}
ll query2(ll root)//操作4
{
return query_seg(1,dfn[root],dfn[root]+siz[root]-1)%Mod;
}
void init()//dfs,建树
{
chainsplit_dfs1(rt,0,1);
cnt=0;
chainsplit_dfs2(rt,rt);
build_segtree(1,1,cnt);
return ;
}
int main()
{
//ios::sync_with_stdio(false);
//cin.tie(nullptr);
n=read(),m=read(),rt=read(),Mod=read();
For(i,1,n) nums[i]=read();
For(i,1,n-1)
{
x=read(),y=read();
v[x].push_back(y);
v[y].push_back(x);
}
init();
For(i,1,m)
{
opt=read();
if(opt==1)
{
x=read(),y=read(),z=read();
update1(x,y,z);
}
if(opt==2)
{
x=read(),y=read();
printf("%lld\n",query1(x,y)%Mod);
}
if(opt==3)
{
x=read(),z=read();
update2(x,z);
}
if(opt==4)
{
x=read();
printf("%lld\n",query2(x)%Mod);
}
}
return 0;
}
调了很久实在找不出问题在哪里awa