树链剖分

贡献者:wlj_55 类别:代码 时间:2019-10-25 16:15:42 收藏数:8 评分:0
返回上页 举报此文章
请选择举报理由:




收藏到我的文章 改错字
#include<bits/stdc++.h>
#define int long long
using namespace std;
int first[300005],next[300005],to[300005],tot=0;
int father[300005],son[300005],size[300005],dep[300005];
int top[300005],rev[300005],seg[300005],a[300005],ind=0;
int sum[1200005],addv[1200005];
int n,m,r,p;
int Read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-1;
ch=getchar();
}
while(isdigit(ch)){
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return x*f;
}
void add(int x,int y){
next[++tot]=first[x];
first[x]=tot;
to[tot]=y;
}
void dfs1(int u,int fa){
father[u]=fa;
size[u]=1;
dep[u]=dep[fa]+1;
int e,v;
for(e=first[u];e,v=to[e];e=next[e]){
if(v!=fa){
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]]) son[u]=v;
}
}
}
void dfs2(int u,int tp){
top[u]=tp;
seg[u]=++ind;
rev[seg[u]]=u;
if(son[u]) dfs2(son[u],tp);
int e,v;
for(e=first[u];e,v=to[e];e=next[e]){
if(!top[v]) dfs2(v,v);
}
}
void pushup(int o){
sum[o]=sum[o<<1]+sum[o<<1|1];
sum[o]%=p;
}
void build(int o,int l,int r){
if(l==r){
sum[o]=a[rev[l]];
sum[o]%=p;
return;
}
int mid=(l+r)>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
pushup(o);
}
void Add(int o,int l,int r,int x){
sum[o]+=(r-l+1)*x;
sum[o]%=p;
}
void pushdown(int o,int l,int r){
if(addv[o]){
addv[o<<1]+=addv[o];
addv[o<<1]%=p;
addv[o<<1|1]+=addv[o];
addv[o<<1|1]%=p;
int mid=(l+r)>>1;
Add(o<<1,l,mid,addv[o]);
Add(o<<1|1,mid+1,r,addv[o]);
addv[o]=0;
}
}
void modify(int o,int l,int r,int nl,int nr,int x){
if(nl<=l&&r<=nr){
addv[o]+=x;
addv[o]%=p;
sum[o]+=(r-l+1)*x;
sum[o]%=p;
return;
}
pushdown(o,l,r);
int mid=(l+r)>>1;
if(nl<=mid) modify(o<<1,l,mid,nl,nr,x);
if(mid<nr) modify(o<<1|1,mid+1,r,nl,nr,x);
sum[o]=sum[o<<1]+sum[o<<1|1];
sum[o]%=p;
}
int query(int o,int l,int r,int nl,int nr){
if(nl<=l&&r<=nr){
return sum[o]%p;
}
pushdown(o,l,r);
int mid=(l+r)>>1,ans=0;
if(nl<=mid) ans+=query(o<<1,l,mid,nl,nr);
ans%=p;
if(mid<nr) ans+=query(o<<1|1,mid+1,r,nl,nr);
return ans%p;
}
void change(int x,int y,int w){
int fx=top[x],fy=top[y];
while(fx!=fy){
if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
modify(1,1,ind,seg[fx],seg[x],w);
x=father[fx];
fx=top[x];
}
if(dep[x]>dep[y]) swap(x,y);
modify(1,1,ind,seg[x],seg[y],w);
}
int Ask(int x,int y){
int fx=top[x],fy=top[y],ans=0;
while(fx!=fy){
if(dep[fx]<dep[fy]) swap(x,y),swap(fx,fy);
ans+=query(1,1,ind,seg[fx],seg[x]);
ans%=p;
x=father[fx];
fx=top[x];
}
if(dep[x]>dep[y]) swap(x,y);
ans+=query(1,1,ind,seg[x],seg[y]);
return ans%p;
}
signed main(){
n=Read(),m=Read(),r=Read(),p=Read();
for(int i=1;i<=n;i++) a[i]=Read();
for(int i=1;i<n;i++){
int x=Read(),y=Read();
add(x,y);
add(y,x);
}
dfs1(r,0);
dfs2(r,r);
build(1,1,ind);
for(int i=1;i<=m;i++){
int opt,x,y,k;
opt=Read();
switch(opt){
case 1:x=Read(),y=Read(),k=Read();if(x>y) swap(x,y);change(x,y,k);break;
case 2:x=Read(),y=Read();if(x>y) swap(x,y);printf("%lld\n",Ask(x,y)%p);break;
case 3:x=Read(),y=Read();modify(1,1,ind,seg[x],seg[x]+size[x]-1,y);break;
case 4:x=Read();printf("%lld\n",query(1,1,ind,seg[x],seg[x]+size[x]-1)%p);break;
}
}
}
声明:以上文章均为用户自行添加,仅供打字交流使用,不代表本站观点,本站不承担任何法律责任,特此声明!如果有侵犯到您的权利,请及时联系我们删除。
文章热度:
文章难度:
文章质量:
说明:系统根据文章的热度、难度、质量自动认证,已认证的文章将参与打字排名!

本文打字排名TOP20

登录后可见

用户更多文章推荐