悬赏5只奶贝&&WA#2-7 TLE#7-10 AC#1和#11
查看原帖
悬赏5只奶贝&&WA#2-7 TLE#7-10 AC#1和#11
746790
space_sea楼主2025/1/25 14:38

***无话可说,下载第一个测试点后Debug完再一次提交,结果就只对了第一个测试点.
五彩斑斓的黑

#include <bits/stdc++.h>
using namespace std;
const int N=4e5+10;
int n, m, r, q;
int a[N];
struct Segment_Tree{
    struct Node{
        int sum, vis;
    }e[N<<1];
    void Build(int x, int l, int r, int rev[]){
        if (l==r){
            e[x].sum=a[rev[l]]%q;
            return ;
        }
        int mid=(l+r)>>1;
        Build(x<<1, l, mid, rev);
        Build(x<<1|1, mid+1, r, rev);
        e[x].sum=(e[x<<1].sum+e[x<<1|1].sum)%q;
    }
    void Down(int x, int l, int r){
        int mid=(l+r)>>1;
        e[x<<1].vis=(e[x<<1].vis+e[x].vis)%q;
        e[x<<1|1].vis=(e[x<<1|1].vis+e[x].vis)%q;
        e[x<<1].sum=(e[x<<1].sum+(mid-l+1)*e[x].vis)%q;
        e[x<<1|1].sum=(e[x<<1|1].sum+(r-mid)*e[x].vis)%q;
        e[x].vis=0;
    }
    void Add(int x, int l, int r, int L, int R, int w){
        if (L<=l&&r<=R){
            e[x].vis=(e[x].vis+w)%q;
            e[x].sum=(e[x].sum+(r-l+1)*w)%q;
            return ;
        }
        Down(x, l, r);
        int mid=(l+r)>>1;
        if (L<=mid){
            Add(x<<1, l, mid, L, R, w);
        }
        if (mid+1<=R){
            Add(x<<1|1, mid+1, r, L, R, w);
        }
        e[x].sum=(e[x<<1].sum+e[x<<1|1].sum)%q;
    }
    int Query(int x, int l, int r, int L, int R){
        if (L<=l&&r<=R){
            return e[x].sum;
        }
        Down(x, l, r);
        int mid=(l+r)>>1, ans=0;
        if (L<=mid){
            ans=(ans+Query(x<<1, l, mid, L, R))%q;
        }
        if (mid+1<=R){
            ans=(ans+Query(x<<1|1, mid+1, r, L, R))%q;
        }
        return ans;
    }
};
struct Chain_Tree{
    Segment_Tree Seg;
    int cnt, num=1, root;
    int father[N], son[N], top[N];
    int size[N], dep[N];
    int seg[N], rev[N];
    int head[N], to[N<<1], nxt[N<<1];
    void Add(int u, int v){
        to[++cnt]=v;
        nxt[cnt]=head[u];
        head[u]=cnt;
    }
    void Dfs1(int u, int fa){
        father[u]=fa;
        dep[u]=dep[fa]+1;
        size[u]=1;
        for (int i=head[u]; i; i=nxt[i]){
            int v=to[i];
            if (v==fa){
                continue;
            }
            Dfs1(v, u);
            size[u]+=size[v];
            if (size[v]>size[son[u]]){
                son[u]=v;
            }
        }
    }
    void Dfs2(int u, int fa){
        if (son[u]){
            int v=son[u];
            top[v]=top[u];
            seg[v]=++num;
            rev[num]=v;
            Dfs2(v, u);
        }
        for (int i=head[u]; i; i=nxt[i]){
            int v=to[i];
            if (v==fa||v==son[u]){
                continue;
            }
            top[v]=v;
            seg[v]=++num;
            rev[num]=v;
            Dfs2(v, u);
        }
    }
    void Add_Line(int x, int y, int z){
        int fx=top[x], fy=top[y];
        while (fx!=fy){
            if (dep[fx]<dep[fy]){
                swap(fx, fy);
                swap(x, y);
            }
            Seg.Add(1, 1, n, seg[x], seg[fx], z);
            x=fx, fx=father[x];
        }
        Seg.Add(1, 1, n, seg[fx], seg[fy], z);
    }
    void Add_Tree(int x, int z){
        Seg.Add(1, 1, n, seg[x], seg[x]+size[x]-1, z);
    }
    int Query_Tree(int x){
        return Seg.Query(1, 1, n, seg[x], seg[x]+size[x]-1);
    }
    int Query_Line(int x, int y){
        int fx=top[x], fy=top[y], ans=0;
        while (fx!=fy){
            if (dep[fx]<dep[fy]){
                swap(fx, fy);
                swap(x, y);
            }
            ans=(ans+Seg.Query(1, 1, n, seg[x], seg[fx]))%q;
            x=fx, fx=father[x];
        }
        ans=(ans+Seg.Query(1, 1, n, seg[fx], seg[fy]))%q;
        return ans;
    }
    void Init(){
        root=r;
        seg[root]=top[root]=1;
        rev[1]=root;
        Dfs1(root, 0);
        Dfs2(root, 0);
        Seg.Build(1, 1, n, rev);
    }
}tree;
int main(){
    ios::sync_with_stdio(0);
    cin.tie();
    cin >> n >> m >> r >> q;
    for (int i=1; i<=n; i++){
        cin >> a[i];
    }
    for (int i=1; i<n; i++){
        int u, v;
        cin >> u >> v;
        tree.Add(u, v);
        tree.Add(v, u);
    }
    tree.Init();
    for (int i=1; i<=m; i++){
        int opt;
        cin >> opt;
        if (opt==1){
            int x, y, z;
            cin >> x >> y >> z;
            tree.Add_Line(x, y, z);
        }
        if (opt==2){
            int x, y;
            cin >> x >> y;
            printf("%d\n", tree.Query_Line(x, y));
        }
        if (opt==3){
            int x, z;
            cin >> x >> z;
            tree.Add_Tree(x, z);
        }
        if (opt==4){
            int x;
            cin >> x;
            printf("%d\n", tree.Query_Tree(x));
        }
    }
    return 0;
}
2025/1/25 14:38
加载中...