Tree chain split Template

Source: Internet
Author: User

Attention
When seeking subtrees, the sub-tree DFS sequence is used consecutively, but not in the following way (sub represents the largest DFS order in the subtree of x):

void dfs2(int x, int t) {    top[x] = t;    dfn[x] = ++cnt;    subcnt = max(subcnt, cnt);    rnk[cnt] = x;    sub[x] = cnt;    if(!son[x]) return;    dfs2(son[x], t);    for(int i=last[x]; i; i=e[i].to) {        int v = e[i].v;        if(v != son[x] && v != fa[x]) {            dfs2(v, v);        }    }    sub[x] = subcnt;}

Because this will not handle the leaf node (directly returned)
The best way to do this is to figure it out with size.
dfn[x] + siz[x] - 1
More details, all in the comments.
Repetition of variable names is really scary ... I haven't seen it in a while.

#include <algorithm> #include <iostream> #include <cstring> #include <cstdio>using namespace STD; #define DEBUG (x) cerr << #x << "=" << x << endl;const int maxn = 100000 + 10;const int maxm = 2 * maxn;int N,m,ans,vis[maxn],edge_tot,r,p,dep[maxn],son[maxn],top[maxn],dfn[maxn],fa[maxn];int siz[MAXN],rnk[    maxn],cnt,sub[maxn],subcnt,last[maxn],a[maxn];struct edge{int u,v,to; Edge () {} edge (int u, int v, int to): U (U), V (v), to (to) {}}e[maxm];inline void Add (int u, int v) {E[++edge_tot] =    Edge (U, V, last[u]); Last[u] = Edge_tot;} struct segment{int siz,sum,add;}    TR[MAXN * 4];void Down (int. now) {tr[now*2].sum + = Tr[now*2].siz * TR[NOW].ADD;    Tr[now*2+1].sum + = Tr[now*2+1].siz * TR[NOW].ADD;    Tr[now*2].sum%= p;    Tr[now*2+1].sum%= p;    Tr[now*2].add + = Tr[now].add;    Tr[now*2+1].add + = Tr[now].add; Tr[now].add = 0;}    void Update (int pos) {tr[pos].siz = Tr[pos*2].siz + tr[pos*2+1].siz; Tr[pos].sum = tr[pos*2].suM + tr[pos*2+1].sum; Tr[pos].sum%= p;}        void build_segment (int now, int l, int r) {if (L = = r) {tr[now].siz = 1;    Tr[now].sum = a[rnk[l]];//The number of the corresponding point of the DFS order, then its value, here is not a[l], is the corresponding point number return;    } int mid = l+r>>1;    Build_segment (Now*2, L, mid);    Build_segment (Now*2+1, mid+1, R); Update (now);}         void Change (int. now, int l, int r, int x, int y, int k) {if (x <= l && r <= y) {tr[now].add + = k;        Tr[now].sum + = Tr[now].siz * k;        Tr[now].sum%= p;    Return    } down (now);    int mid = l+r>>1;    if (x <= mid)//with no left son to go, just look for the change border changes (Now*2, L, Mid, X, Y, k);    if (Y > Mid) Change (now*2+1, mid+1, R, X, y, k); Update (now);}    int query (int now, int l, int r, int x, int y) {if (x <= l && r <= y) {return tr[now].sum% P;    } down (now);    A long long sum = 0;    int mid = l+r>>1;    if (x <= mid) sum + = query (Now*2, L, Mid, X, y);  if (Y > mid)      Sum + = Query (now*2+1, mid+1, R, X, y);    Sum%= p; return sum;}    void dfs1 (int x, int f, int depth) {fa[x] = f;    DEP[X] = depth;    SIZ[X] = 1;        for (int i=last[x]; i; i=e[i].to) {int v = E[I].V;        if (v = = f) continue;//is executed continue instead of v!=f, because that would be to increase the parentheses ...        DFS1 (V, x, depth + 1);        SIZ[X] + = Siz[v];        if (Siz[v] > Siz[son[x]]) {son[x] = V;    }}}void DFS2 (int x, int t) {top[x] = t;    DFN[X] = ++cnt;    RNK[CNT] = x;    if (!son[x]) return;        DFS2 (Son[x], t);//Ensure that the points on the heavy chain DFS sequential for (int i=last[x]; i; i=e[i].to) {int v = E[I].V;        if (v = son[x] && v! = fa[x]) {DFS2 (V, v);    }}}int path_query (int x, int y) {long long sum = 0; while (top[x]! = Top[y]) {if (Dep[top[x]] < dep[top[y]) swap (x, y);//Let X go deeper, so jump x sum + = query (1, 1, N, DFN        [Top[x]], dfn[x]);//Be sure to write topx instead of tx = TOPX because XY will swap, the advance setting will be messed up ...        Sum%= p;    x = fa[top[x]]; } if (Dfn[x] > Dfn[y]) Swap (x, y);    Sum + = Query (1, 1, N, Dfn[x], dfn[y]);    Sum%= p; return sum;}        void path_update (int x, int y, int k) {while (top[x]! = Top[y]) {if (Dep[top[x] < dep[top[y]]) swap (x, y);        Change (1, 1, N, Dfn[top[x]], dfn[x], k);    x = fa[top[x]];    } if (Dfn[x] > Dfn[y]) swap (x, y); Change (1, 1, N, Dfn[x], Dfn[y], k);}    int main () {scanf ("%d%d%d%d", &n, &m, &r, &p);    for (int i=1; i<=n; i++) {scanf ("%d", &a[i]);        } for (int i=1; i<n; i++) {int x, y;        scanf ("%d%d", &x, &y);        Add (x, y);    Add (y, x);    } dfs1 (r, 0, 1);    DFS2 (R,R);    Build_segment (1, 1, N);        for (int i=1; i<=m; i++) {int cmd,x,y,z;        scanf ("%d", &cmd);            if (cmd = = 1) {scanf ("%d%d%d", &x, &y, &z);        Path_update (x, y, z);            } else if (cmd = = 2) {scanf ("%d%d", &x, &y);        printf ("%d\n", Path_query (x, y)); } else if(cmd = = 3)            {scanf ("%d%d", &x, &y);        Change (1, 1, N, Dfn[x], dfn[x] + siz[x]-1, y);            } else if (cmd = = 4) {scanf ("%d", &x);        printf ("%d\n", Query (1, 1, N, Dfn[x], dfn[x] + siz[x]-1)); }} return 0;}

Two practiced hand questions ... Point modification and Edge modification
Rokua P3128 [usaco15dec] Max flow max flows

, respectively

#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include < ctime>using namespace std; #define DEBUG (x) cerr << #x << "=" << x << endl;const int MAXN = 5000 0 + 10;const int maxm = MAXN * 2;int N,k,dep[maxn],fa[maxn],son[maxn],dfn[maxn],top[maxn],rnk[maxn],dfs_seq,edge_tot,    last[maxn],siz[maxn];struct edge{int u,v,to; Edge () {} edge (int u, int v, int to): U (U), V (v), to {}}E[MAXM];    inline void Add (int u, int v) {E[++edge_tot] = Edge (U, V, last[u]); Last[u] = Edge_tot;} struct segmenttree{int val, tag;}    tr[maxn*4];void (int now) {int tagadd = Tr[now].tag;    Tr[now*2].val + = Tagadd;    Tr[now*2+1].val + = Tagadd;    Tr[now*2].tag + = Tagadd;    Tr[now*2+1].tag + = Tagadd; Tr[now].tag = 0;} void Change (int now, int l, int r, int cx, int cy, int k) {if (CX <= l && R <= Cy) {Tr[now].tag +        = k;        Tr[now].val + = k;    Return    } down (now); int mid = l+r>>1;    if (CX <= mid) Change (Now*2, L, Mid, CX, CY, K);    if (Cy > Mid) Change (now*2+1, mid+1, R, CX, CY, K); Tr[now].val = Max (Tr[now*2].val, tr[now*2+1].val);}    void dfs1 (int x, int father, int depth) {dep[x] = depth;    SIZ[X] = 1;    Fa[x] = father;        for (int i=last[x]; i; i=e[i].to) {int v = E[I].V;        if (v = = father) Continue;        DFS1 (V, X, depth+1);        SIZ[X] + = Siz[v];    if (Siz[v] > Siz[son[x]]) son[x] = v;    }}void DFS2 (int x, int t) {top[x] = t;    DFN[X] = ++dfs_seq;    RNK[DFS_SEQ] = x;    if (!son[x]) return;    DFS2 (Son[x], T);        for (int i=last[x]; i; i=e[i].to) {int v = E[I].V;        if (v = = Fa[x] | | v = = son[x]) continue;    DFS2 (V, v);        }}int path_change (int x, int y, int k) {while (top[x]! = Top[y]) {if (Dep[top[x]] < Dep[top[y]]) swap (x, y);        Change (1, 1, N, Dfn[top[x]], dfn[x], k);    x = fa[top[x]];    } if (Dfn[x] > Dfn[y]) swap (x, y); Change (1,1, N, Dfn[x], Dfn[y], k);}    int main () {scanf ("%d%d", &n, &k);        for (int i=1; i<n; i++) {int u,v;        scanf ("%d%d", &u, &v);        Add (U, v);    Add (V, u);    } dfs1 (1, 0, 1);    DFS2 (1, 1);        for (int i=1; i<=k; i++) {int S, t;        scanf ("%d%d", &s, &t);    Path_change (S, T, 1);    } printf ("%d", tr[1].val); return 0;}

Rokua P3038 [usaco11dec] pasture planting grass planting

#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include < ctime>using namespace std; #define DEBUG (x) cerr << #x << "=" << x << endl;const int MAXN = 1000 xx + 10;const int maxm = MAXN * 2;int N,m,dep[maxn],fa[maxn],son[maxn],dfn[maxn],top[maxn],rnk[maxn],dfs_seq,edge_tot,    last[maxn],siz[maxn];struct edge{int u,v,to; Edge () {} edge (int u, int v, int to): U (U), V (v), to {}}E[MAXM];    inline void Add (int u, int v) {E[++edge_tot] = Edge (U, V, last[u]); Last[u] = Edge_tot;} struct segmenttree{int val, tag;}    Tr[maxn*4];void Down (int. now) {Tr[now*2].tag + = Tr[now].tag;    Tr[now*2+1].tag + = Tr[now].tag;    Tr[now*2].val + = Tr[now].tag;    Tr[now*2+1].val + = Tr[now].tag; Tr[now].tag = 0;}         void Change (int. now, int l, int r, int x, int y, int k) {if (x <= l && r <= y) {tr[now].tag + = k;        Tr[now].val + = k;    Return    } down (now); int mid = L+r>>1;    if (x <= mid) Change (Now*2, L, Mid, X, Y, k); if (Y > Mid) Change (now*2+1, mid+1, R, X, y, k);}    int query (int now, int l, int r, int x) {if (L = = r) return tr[now].val;    Down (now);    int mid = l+r>>1;    if (x <= mid) return query (Now*2, L, Mid, X); else return query (now*2+1, mid+1, R, x);}    void dfs1 (int x, int father, int depth) {dep[x] = depth;    SIZ[X] = 1;    Fa[x] = father;        for (int i=last[x]; i; i=e[i].to) {int v = E[I].V;        if (v = = father) Continue;        DFS1 (V, X, depth+1);        SIZ[X] + = Siz[v];    if (Siz[v] > Siz[son[x]]) son[x] = v;    }}void DFS2 (int x, int t) {top[x] = t;    DFN[X] = ++dfs_seq;    RNK[DFS_SEQ] = x;    if (!son[x]) return;    DFS2 (Son[x], T);        for (int i=last[x]; i; i=e[i].to) {int v = E[I].V;        if (v = = Fa[x] | | v = = son[x]) continue;    DFS2 (V, v); }}void path_change (int x, int y, int k) {while (top[x]! = Top[y]) {if (Dep[top[x]] < DEp[top[y]]) swap (x, y);        Change (1, 1, N, Dfn[top[x]], dfn[x], k);    x = fa[top[x]];    } if (Dfn[x] > Dfn[y]) swap (x, y);    Change (1, 1, N, Dfn[x], Dfn[y], k); Change (1, 1, N, Dfn[x], dfn[x],-K);    int main () {scanf ("%d%d", &n, &m);        for (int i=1; i<n; i++) {int u,v;        scanf ("%d%d", &u, &v);        Add (U, v);    Add (V, u);    } dfs1 (1, 0, 1);    DFS2 (1, 1);        for (int i=1; i<=m; i++) {char cmd;        Cin >> cmd;        int AI, bi;        scanf ("%d%d", &ai, &bi);        if (cmd = = ' P ') {path_change (AI, Bi, 1);        } else {printf ("%d\n", Query (1, 1, N, Max (Dfn[ai], Dfn[bi])); }} return 0;}

Tree Chain template

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.