zoukankan      html  css  js  c++  java
  • 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
    "::"r"(__p__));
    
    
        int T, n, m;
        int a, b, c;
        scanf_(T);
        int Icase = 0;
        while (T--){
            printf("Case #%d:
    ", ++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;
    }
  • 相关阅读:
    Aptana 开发环境执行时默认的工作路径
    python 日志工具 Dict4ini 的简单使用示例
    C语言中的条件编译
    Ammyy Admin 一个小巧方便的远程管理工具
    djangoevolution 插件维持Django 模型和数据库结构一致的基本原理
    关于Django 框架的ContentType 模型
    关于 Django web请求中的Cookie
    GridView中,显示记录的总条数
    SQL 日期格式
    .net如何实现页面间的参数传递
  • 原文地址:https://www.cnblogs.com/yigexigua/p/4099396.html
Copyright © 2011-2022 走看看