难道有什么问题么。。硬是没查出来。。
查看原帖
难道有什么问题么。。硬是没查出来。。
36562
CopperOxide楼主2017/4/23 16:16

大神请勿看,代码又臭又长。。。

#include<bits/stdc++.h>
#define N 100010
using namespace std;
int n,m,r;
int v[N],id[N],son[N],top[N],f[N],pos[N],d[N],siz[N];
int out[N],cnt=0;
long long p;
struct Node{
    int l,r,sum,flag;
}t[3*N];
void build(int k,int l,int r){
    t[k].flag=0;
    t[k].l=l,t[k].r=r;
    if(l==r){
        t[k].sum=v[id[l]];
        return;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    t[k].sum=(t[k<<1].sum+t[k<<1|1].sum)%p;
}
void tag(int k){
    long long x=t[k].flag;
    t[k<<1].flag=(t[k<<1].flag+x)%p;
    t[k<<1].sum=(t[k<<1].sum+(t[k<<1].r-t[k<<1].l+1)*x)%p;
    t[k<<1|1].flag=(t[k<<1|1].flag+x)%p;
    t[k<<1|1].sum=(t[k<<1|1].sum+(t[k<<1|1].r-t[k<<1|1].l+1)*x)%p;
}
void modify(int k,int l,int r,long long v){
    int L=t[k].l,R=t[k].r;
    if(l<=L&&R<=r){
        t[k].flag=(t[k].flag+v)%p;
        t[k].sum=(t[k].sum+(R-L+1)*v)%p;
        return;
    }
    if(t[k].flag) tag(k);
    int mid=(L+R)>>1;
    if(l<=mid&&mid<r){
        modify(k<<1,l,mid,v);
        modify(k<<1|1,mid+1,r,v);
    }
    if(r<=mid) modify(k<<1,l,r,v);
    if(l>mid) modify(k<<1|1,l,r,v);
    t[k].sum=(t[k<<1].sum+t[k<<1|1].sum)%p;
}
long long query(int k,int l,int r){
    int L=t[k].l,R=t[k].r;
    if(l<=L&&R<=r) return t[k].sum;
    if(t[k].flag) tag(k);
    int mid=(L+R)>>1;
    if(r<=mid) return query(k<<1,l,r);
    if(l>mid) return query(k<<1|1,l,r);
    return (query(k<<1,l,mid)+query(k<<1|1,mid+1,r))%p;
}
vector<int> e[N];
void dfs_1(int x,int fa,int dep){
    d[x]=dep;
    siz[x]=1;
    f[x]=fa;
    for(int i=0;i<e[x].size();i++){
        int k=e[x][i];
        if(k==fa) continue;
        dfs_1(k,x,dep+1);
        siz[x]+=siz[k];
        if(siz[son[x]]<siz[k]) son[x]=k;
    }
}
void dfs_2(int x,int tp){
    top[x]=tp;
    pos[x]=out[x]=++cnt;
    id[cnt]=x;
    if(son[x]) dfs_2(son[x],tp);
    for(int i=0;i<e[x].size();i++){
        int k=e[x][i];
        if(k==son[x]||k==f[x]) continue;
        dfs_2(k,k);
        out[x]=max(out[x],out[k]);
    }
    for(int i=0;i<e[x].size();i++){
        int k=e[x][i];
        out[x]=max(out[x],out[k]);
    }
}
int lca(int x,int y){
    for(;top[x]!=top[y];){
        if(d[top[x]]<d[top[y]]) swap(x,y);
        x=f[top[x]];
    }
    return d[x]>d[y]?y:x;
}
void solve(int x,int y,long long v){
    int tx=top[x],ty=top[y];
    while(tx!=ty){
        if(d[tx]<d[ty]){
            swap(tx,ty);
            swap(x,y);
        }
        modify(1,pos[tx],pos[x],v);
        x=f[tx];
        tx=top[x];
    }
    if(d[x]>d[y]) swap(x,y);
    modify(1,pos[x],pos[y],v);
}
long long query(int x,int y){
    long long sum=0;
    int tx=top[x],ty=top[y];
    while(tx!=ty){
        if(d[tx]<d[ty]){
            swap(tx,ty);
            swap(x,y);
        }
        sum=(sum+query(1,pos[tx],pos[x]))%p;
        x=f[tx];
        tx=top[x];
    }
    if(d[x]>d[y]) swap(x,y);
    sum=(sum+query(1,pos[x],pos[y]))%p;
    return sum;
}
int main(){
    scanf("%d%d%d%lld",&n,&m,&r,&p);
    for(int i=1;i<=n;i++) scanf("%lld",&v[i]);
    for(int i=1;i<n;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs_1(r,0,0);
    dfs_2(r,r);
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int key;
        scanf("%d",&key);
        if(key==1){
            int x,y;
            long long v;
            scanf("%d%d%lld",&x,&y,&v);
            solve(x,y,v);
        }
        if(key==2){
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%lld\n",query(x,y));
        }
        if(key==3){
            int x;
            long long v;
            scanf("%d%lld",&x,&v);
            modify(1,pos[x],out[x],v);
        }
        if(key==4){
            int x;
            scanf("%d",&x);
            printf("%lld\n",query(1,pos[x],out[x]));
        }
    }
    return 0;
}

2017/4/23 16:16
加载中...