首页 > 代码库 > Hdu5044Tree 树链剖分

Hdu5044Tree 树链剖分

  输入输出挂,扩栈挂,模板树链剖分。

#include<iostream>#include<cstdio>#include<cstring>#include<map>#include<vector>#include<stdlib.h>#include<algorithm>using namespace std;const int maxn = 111111;struct Node{    int next; int to;}e[maxn * 2];int len;int z;int size[maxn], son[maxn], father[maxn], deep[maxn], pos[maxn], top[maxn], vis[maxn], color[maxn];int head[maxn], val[maxn];inline bool scanf_(int &ret) {    char c; int sgn;    if (c = getchar(), c == EOF) return 0; //EOF    while (c != - && (c<0 || c>9)) c = getchar();    sgn = (c == -) ? -1 : 1;    ret = (c == -) ? 0 : (c - 0);    while (c = getchar(), c >= 0&&c <= 9) ret = ret * 10 + (c - 0);    ret *= sgn;    return 1;}inline void printf_(int x) {    if (x>9) printf_(x / 10);    putchar(x % 10 + 0);}void add(int from, int to){    e[len].to = to;    e[len].next = head[from];    head[from] = len++;}void init(int x){    size[x] = 1; son[x] = 0;    for (int i = head[x]; i != -1; i = e[i].next){        int cc = e[i].to;        if (cc == father[x]) continue;        father[cc] = x;        deep[cc] = deep[x] + 1;        init(cc);        size[x] += size[cc];        if (size[son[x]]<size[cc]) son[x] = cc;    }}void dfs(int x, int tp){    pos[x] = ++z; vis[z] = x; top[x] = tp;    if (son[x]) dfs(son[x], tp);    for (int i = head[x]; i != -1; i = e[i].next){        int cc = e[i].to;        if (cc == father[x] || cc == son[x]) continue;        dfs(cc, cc);    }}void gao(int x, int y, int add){    int fx = top[x]; int fy = top[y];    while (fx != fy){        if (deep[fx]<deep[fy]){            swap(x, y); swap(fx, fy);        }        color[pos[fx]] += add; color[pos[x] + 1] -= add;        x = father[fx]; fx = top[x];    }    if (deep[x]>deep[y]) swap(x, y);    color[pos[x]] += add; color[pos[y] + 1] -= add;}int color1[maxn];void gao1(int x, int y, int add){    int fx = top[x]; int fy = top[y];    while (fx != fy){        if (deep[fx]<deep[fy]){            swap(x, y); swap(fx, fy);        }        color1[pos[fx]] += add; color1[pos[x] + 1] -= add;        x = father[fx]; fx = top[x];    }    if (x == y) return;    if (deep[x]>deep[y]) swap(x, y);    color1[pos[son[x]]] += add; color1[pos[y] + 1] -= add;}int ans[maxn];char str[100];int edge[maxn][2];int main(){    int __size__ = 256 << 20;    char * __p__ = (char *)malloc(__size__) + __size__;    __asm__("movl %0,%%esp\n"::"r"(__p__));    int T, n, m;    int a, b, c;    scanf_(T);    int Icase = 0;    while (T--){        printf("Case #%d:\n", ++Icase);        scanf_(n); scanf_(m);        len = 0; z = 0;        memset(head, -1, sizeof(head));        memset(color, 0, sizeof(color));        memset(val, 0, sizeof(val));        memset(color1, 0, sizeof(color1));        for (int i = 0; i<n - 1; i++){            scanf_(edge[i][0]); scanf_(edge[i][1]);            add(edge[i][0], edge[i][1]); add(edge[i][1], edge[i][0]);        }        father[1] = 1;        init(1); dfs(1, 1);        for (int i = 0; i<n - 1; i++){            a = edge[i][0]; b = edge[i][1];            if (deep[a]>deep[b]) swap(edge[i][0], edge[i][1]);            ans[i] = pos[edge[i][1]];        }        for (int i = 0; i<m; i++){            scanf("%s", str);            scanf_(a); scanf_(b); scanf_(c);            if (strcmp(str, "ADD1") == 0){                gao(a, b, c);            }            else gao1(a, b, c);        }        for (int i = 1; i <= n; i++) color[i] += color[i - 1];        for (int i = 1; i <= n; i++) color1[i] += color1[i - 1];        for (int i = 1; i <= n; i++){            int t = vis[i];            val[t] = color[i];        }        printf_(val[1]);        for (int i = 2; i <= n; i++){            putchar( );            printf_(val[i]);        }        cout << endl;        for (int i = 0; i<n - 1; i++){            if (i) putchar( );            int t = ans[i];            printf_(color1[t]);        }        cout << endl;    }    return 0;}

 

Hdu5044Tree 树链剖分