树剖板子,所有输出都比标准多1,求助
查看原帖
树剖板子,所有输出都比标准多1,求助
434015
Calanosay楼主2021/6/2 14:53
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
const int maxm=2e5+5;
#define lson node<<1
#define rson node<<1|1
int n,m,r,mod,idx;
int head[maxn],w[maxm],v[maxm],nex[maxm],cnt,son[maxn],size[maxn],dep[maxn],top[maxn];
int fa[maxn];
int p[maxn],id[maxn],pre[maxn];
struct node{
    int l,r,val,lazy;
}t[maxn<<2];
void add(int x,int y){
    v[++cnt]=y;
    nex[cnt]=head[x];
    head[x]=cnt;
}
void dfs(int u,int f,int deep){
    dep[u]=deep;
    size[u]=1;
    fa[u]=f;
    int maxx=-1;
    for(int i=head[u];i;i=nex[i]){
        int to=v[i];
        if(f==to)  continue;
        dfs(to,u,deep+1);
        size[u]+=size[to];
        if(size[to]>maxx)   {maxx=size[to];son[u]=to;}
    }

}
void dfs2(int node,int tope){
    id[node]=++idx;
    pre[idx]=node;
    top[node]=tope;
    if(!son[node])  return;
    dfs2(son[node],tope);
    for(int i=head[node];i;i=nex[i]){
        int to=v[i];
        if(to==fa[node]||to==son[node]) continue;
        dfs2(to,to);
    }
}
//开始线段树
void pushup(int node){
    t[node].val=(t[lson].val+t[rson].val)%mod;
}
void spread(int node){
    if(t[node].lazy){
        t[lson].lazy=(t[lson].lazy+t[node].lazy)%mod;
        t[rson].lazy=(t[rson].lazy+t[node].lazy)%mod;
        t[lson].val=(t[lson].val+t[node].lazy*(t[lson].r-t[lson].l+1))%mod;
        t[rson].val=(t[rson].val+t[node].lazy+(t[rson].r-t[rson].l+1))%mod;
        t[node].lazy=0;
    }
}
void build(int start,int end,int node){
    t[node].l=start,t[node].r=end;
    if(start==end){
        t[node].val=p[pre[start]];
        return;
    }
    int mid=start+end>>1;
    build(start,mid,lson);
    build(mid+1,end,rson);
    pushup(node);
}
void update(int start,int end,int node,int k){
    int l=t[node].l,r=t[node].r;
    if(start<=l&&r<=end){
        t[node].lazy+=k;
        t[node].val=(t[node].val+k*(r-l+1))%mod;
        return;
    }
    spread(node);
    int mid=l+r>>1;
    if(start<=mid) update(start,end,lson,k);
    if(end>mid) update(start,end,rson,k);
    pushup(node);

}
int query(int start,int end,int node){
    int l=t[node].l,r=t[node].r;
    if(start<=l&&r<=end){
        return t[node].val;
    }
    spread(node);
    int ans=0;
    int mid=l+r>>1;
    if(start<=mid)  ans+=query(start,end,lson);
    if(end>mid)     ans+=query(start,end,rson);
    return ans%mod;
}
void myupdate(int x,int y,int k){
    k%=mod;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        update(id[top[x]],id[x],1,k);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    update(id[x],id[y],1,k);
}
int myquery(int x,int y){
    int ans=0;
    while (top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        ans+=query(id[top[x]],id[x],1);
        ans%=mod;
        x=fa[top[x]];
    }
    if(dep[x]>dep[y])   swap(x,y);
    ans+= query(id[x],id[y],1);
    return ans%mod;
}
void treeupdate(int x,int k){
    update(id[x],id[x]+size[x]-1,1,k);
}
int treequery(int x){
    return query(id[x],id[x]+size[x]-1,1);
}
int main(){
        cin>>n>>m>>r>>mod;
        for(int i=1;i<=n;i++)   cin>>p[i];
        for(int i=1;i<=n-1;i++){
            int x,y;
            cin>>x>>y;
            add(x,y);add(y,x);
        }
    dfs(r,0,1);
    dfs2(r,r);
    build(1,n,1);
        while(m--){
            int op,x,y,z;
            cin>>op;
            if(op==1){
                cin>>x>>y>>z;
                myupdate(x,y,z);
            }
            if(op==2){
                cin>>x>>y;
                cout<<myquery(x,y)<<endl;

            }
            if(op==3){
                cin>>x>>z;
                treeupdate(x,z);
            }
            if(op==4){
                cin>>x;
                cout<<treequery(x)<<endl;
            }
        }
}

每个样例都比答案多了1,不知道为什么

2021/6/2 14:53
加载中...