potatoler 树剖打烂了,大家快来帮帮她吧!
查看原帖
potatoler 树剖打烂了,大家快来帮帮她吧!
235832
potatoler楼主2020/6/2 18:21

如题,鄙人代码如下。多谢各位大佬出手相助!

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#define thisSon edge[i].destiVertex
#define xTop vertex[x].chainTop
#define yTop vertex[y].chainTop
using namespace std;
const int MaxN = 1000005;
int n, m, root, mod, res, finalVal[MaxN];
struct Vertex{
    int val, father, depth, subtreeSize, heavySon, chainTop, DFN;
}vertex[MaxN];
struct Edge{
    int destiVertex, nextEdge;
}edge[MaxN * 2];
struct SegmentTree{
    int data, addTag, l, r;
}seg[MaxN * 4];
int tot, head[MaxN], cntDFN;

inline void AddEdge(int u,int v){
    tot++;
    edge[tot].destiVertex = v;
    edge[tot].nextEdge = head[u];
    head[u] = tot;
}

inline void PassTag(int x){
    seg[x*2].addTag += seg[x].addTag;
    seg[x*2+1].addTag += seg[x].addTag;
    seg[x*2].data = (seg[x*2].data + seg[x].addTag * (seg[x*2].r - seg[x*2].l + 1) % mod) % mod;
    seg[x*2+1].data = (seg[x*2+1].data + seg[x].addTag * (seg[x*2+1].r - seg[x*2+1].l + 1) % mod) % mod;
    seg[x].addTag = 0;
}

inline void Build(int x,int l,int r){
    seg[x].l = l;
    seg[x].r = r;
    if(l == r){
        seg[x].data = finalVal[l];
        if(seg[x].data > mod) seg[x].data %= mod;
        return;
    }
    int mid = (l + r) / 2;
    Build(x*2, l, mid);
    Build(x*2+1, mid+1, r);
    seg[x].data = (seg[x*2].data + seg[x*2+1].data) % mod;
}

inline void Ask(int x, int l, int r){
    if(l <= seg[x].l && r >= seg[x].r){
        res = (res + seg[x].data) % mod;
        return;
    }
    else{
        if(seg[x].addTag) PassTag(x);
        int mid = (seg[x].l + seg[x]. r) / 2;
        if(l <= mid) Ask(x*2, l, r);
        if(r > mid) Ask(x*2+1, l, r);
    }
}

inline void Addition(int x, int l, int r, int z){
    if(l <= seg[x].l && r >= seg[x].r){
        seg[x].addTag += z;
        seg[x].data = (seg[x].data + z * (seg[x].r - seg[x].l + 1)) % mod;
    }
    else{
        if(seg[x].addTag) PassTag(x);
        int mid = (seg[x].l + seg[x].r) / 2;
        if(l <= mid) Addition(x*2, l, r, z);
        if(r > mid) Addition(x*2+1, l, r, z);
        seg[x].data = (seg[x*2].data + seg[x*2+1].data) % mod;
    }
} 
inline int WayAsk(int x,int y){
    int ans=0;
    while(xTop != yTop){
        if(vertex[xTop].depth < vertex[yTop].depth) swap(x, y);
        res = 0;
        Ask(1, vertex[xTop].DFN, vertex[x].DFN);
        ans += res;
        ans %= mod;
        x = vertex[xTop].father;
    }
    if(vertex[x].depth > vertex[y].depth) swap(x, y);
    res = 0;
    Ask(1, vertex[x].DFN, vertex[y].depth);
    ans += res;
    return ans % mod;
}

inline void WayAdd(int x,int y,int k){
    k %= mod;
    while(xTop != yTop){
        if(vertex[xTop].depth < vertex[yTop].depth) swap(x,y);
        Addition(1, vertex[xTop].DFN, vertex[x].DFN,k);
        x = vertex[xTop].father;
    }
    if(vertex[x].depth > vertex[y].depth) swap(x, y);
    Addition(1, vertex[x].DFN, vertex[y].DFN, k);
}

inline int SubtreeAsk(int x){
    res = 0;
    Ask(1, vertex[x].DFN, vertex[x].DFN + vertex[x].subtreeSize - 1);
    return res;
}

inline void SubtreeAdd(int x,int k){
    Addition(1, vertex[x].DFN, vertex[x].DFN + vertex[x].subtreeSize - 1, k);
}

inline void DFS1(int x){
    vertex[x].heavySon = -1;
    vertex[x].subtreeSize = 1;
    for(int i = head[x]; i; i = edge[i].nextEdge){
        if(thisSon == vertex[x].father) continue;
        vertex[thisSon].depth = vertex[x].depth + 1;
        vertex[thisSon].father = x;
        DFS1(thisSon);
        vertex[x].subtreeSize += vertex[thisSon].subtreeSize;
        if(vertex[x].heavySon == -1 || vertex[thisSon].subtreeSize > vertex[vertex[x].heavySon].subtreeSize) vertex[x].heavySon = thisSon;
    }
}

inline void DFS2(int x, int top){
    vertex[x].DFN = ++cntDFN;
    finalVal[cntDFN] = vertex[x].val;
    vertex[x].chainTop = top;
    if(vertex[x].heavySon == -1) return;
    DFS2(vertex[x].heavySon, top);
    for(int i = head[x]; i; i = edge[i].nextEdge){
        if(thisSon == vertex[x].father || thisSon == vertex[x].heavySon) continue;
        DFS2(thisSon, thisSon);
    }
}

int main(){
    scanf("%d%d%d%d",&n,&m,&root,&mod);
    for(int i = 1; i <= n; i++) scanf("%d",&vertex[i].val);
    for(int i = 1; i < n; i++){
        int u, v;
        scanf("%d%d",&u,&v);
        AddEdge(u, v);
        AddEdge(v, u);
    }
    vertex[root].father = 0;
    vertex[root].depth = 1;
    DFS1(root);
    DFS2(root, root);
    Build(1,1,n);
    while(m--){
        int op, x, y, z;
        scanf("%d",&op);
        if(op == 1){
            scanf("%d%d%d",&x,&y,&z);
            WayAdd(x, y, z);
        }
        if(op == 2){
            scanf("%d%d",&x,&y);
            printf("%d\n",WayAsk(x, y));
        }
        if(op == 3){
            scanf("%d%d",&x,&z);
            SubtreeAdd(x, z);
        }
        if(op == 4){
            scanf("%d",&x);
            printf("%d\n",SubtreeAsk(x));
        }
    }
}
2020/6/2 18:21
加载中...