• 树链剖分学习记录


    HDU  3966 

    基于点权 改动(增减)一条路径上的点  单结点查询

    code:

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 50010;
    struct Edge{
        int to, next;
    }edge[maxn*2];
    int head[maxn], tot;
    int top[maxn];
    int fa[maxn];
    int deep[maxn];
    int num[maxn];
    int p[maxn];
    int fp[maxn];
    int son[maxn];
    int pos;
    void init(){
        tot = 0;
        memset(head, -1, sizeof(head));
        pos = 1;
        memset(son, -1, sizeof(son));
    }
    void add_Edge(int u, int v){
        edge[tot].to = v;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    void dfs1(int u, int pre, int d){
        deep[u] = d;
        fa[u] = pre;
        num[u] = 1;
        for(int i = head[u]; i != -1; i = edge[i].next){
            int v = edge[i].to;
            if(v == pre) continue;
            dfs1(v, u, d+1);
            num[u] += num[v];
            if(son[u] == -1 || num[v] > num[son[u]]) son[u] = v;
        }
    }
    void getpos(int u, int sp){
        top[u] = sp;
        p[u] = pos++;
        fp[p[u]] = u;
        if(son[u] == -1) return;
        getpos(son[u], sp);
        for(int i = head[u]; i != -1; i = edge[i].next){
            int v = edge[i].to;
            if(v == son[u]) continue;
            if(v == fa[u]) continue;
            getpos(v, v);
        }
    }
    
    int n;
    int a[maxn];
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    int sum[maxn<<2],col[maxn<<2];
    void pushdown(int rt, int m)
    {
        if(col[rt])
        {
            col[rt<<1] += col[rt];
            col[rt<<1|1] += col[rt];
            sum[rt<<1] += (m-(m>>1))*col[rt];
            sum[rt<<1|1] += (m>>1)*col[rt];
            col[rt] = 0;
        }
    }
    void build(int l,int r,int rt)
    {
        col[rt]=0;
        if(l==r)
        {
            sum[rt] = a[fp[l]];
            return;
        }
        int m=(l+r)>>1;
        build(lson);
        build(rson);
    }
    void update(int L,int R,int c,int l,int r,int rt)
    {
        if(L<=l&&R>=r)
        {
            col[rt] += c;
            sum[rt] += c*(r-l+1);
            return;
        }
        pushdown(rt,r-l+1);
        int m=(l+r)>>1;
        if(L<=m)
            update(L,R,c,lson);
        if(R>m)
            update(L,R,c,rson);
    }
    int query(int p, int l, int r, int rt){
        if(l == r) return sum[rt];
        pushdown(rt, r-l+1);
        int m = (l + r) >> 1;
        if(p <= m) return query(p, lson);
        else return query(p, rson);
    }
    
    void change(int u, int v, int val){
        int f1 = top[u], f2 = top[v];
        while(f1 != f2){
            if(deep[f1] < deep[f2]){
                swap(f1, f2);
                swap(u, v);
            }
            update(p[f1], p[u], val, 1, n, 1);
            u = fa[f1];
            f1 = top[u];
        }
        if(deep[u] > deep[v]) swap(u, v);
        update(p[u], p[v], val, 1, n, 1);
    }
    int main(){
        int M, P;
        while(scanf("%d%d%d",&n, &M, &P) != EOF){
            init();
            for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
            int u, v;
            while(M--){
                scanf("%d%d",&u, &v);
                add_Edge(u, v);
                add_Edge(v, u);
            }
            dfs1(1, 0, 0);
            getpos(1, 1);
            build(1, n, 1);
            char op[10];
            int x, y, z;
            while(P--){
                scanf("%s", op);
                if(op[0] == 'I'){
                    scanf("%d%d%d",&x, &y, &z);
                    change(x, y, z);
                }
                else if(op[0] == 'D'){
                    scanf("%d%d%d",&x, &y, &z);
                    change(x, y, -z);
                }
                else{
                    scanf("%d",&x);
                    printf("%d
    ",query(p[x], 1, n, 1));
                }
            }
        }
        return 0;
    }
    



    SPOJ QTREE(树链剖分)

    基于边权  改动单条边权  查询路径边权最大值

    code:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define INF 0x3f3f3f3f
    using namespace std;
    
    const int maxn = 10010;
    struct Edge{
        int to, next;
    }edge[maxn*2];
    int head[maxn], tot;
    int top[maxn];
    int fa[maxn];
    int deep[maxn];
    int num[maxn];
    int p[maxn];
    int fp[maxn];
    int son[maxn];
    int pos;
    void init(){
        tot = 0;
        memset(head, -1, sizeof(head));
        pos = 1;
        memset(son, -1, sizeof(son));
    }
    void add_Edge(int u, int v){
        edge[tot].to = v;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    void dfs1(int u, int pre, int d){
        deep[u] = d;
        fa[u] = pre;
        num[u] = 1;
        for(int i = head[u]; i != -1; i = edge[i].next){
            int v = edge[i].to;
            if(v != pre){
                dfs1(v, u, d+1);
                num[u] += num[v];
                if(son[u] == -1 || num[v] > num[son[u]]){
                    son[u] = v;
                }
            }
        }
    }
    void getpos(int u, int sp){
        top[u] = sp;
        p[u] = pos++;
        fp[p[u]] = u;
        if(son[u] == -1) return;
        getpos(son[u], sp);
        for(int i = head[u]; i != -1; i = edge[i].next){
            int v = edge[i].to;
            if(v != fa[u] && v != son[u]){
                getpos(v, v);
            }
        }
    }
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    int n;
    int sum[maxn<<4];
    void pushup(int rt){
        sum[rt] = max(sum[rt<<1], sum[rt<<1|1]);
    }
    void build(int l, int r, int rt){
        sum[rt] = 0;
        if(l == r) return;
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    void update(int pp, int vv, int l, int r, int rt){
        if(l == r){
            sum[rt] = vv;
            return;
        }
        int m = (l + r) >> 1;
        if(pp <= m) update(pp, vv, lson);
        else update(pp, vv, rson);
        pushup(rt);
    }
    int query(int L, int R, int l, int r, int rt){
        if(L <= l && R >= r){
            return sum[rt];
        }
        int m = (l + r) >> 1;
        int ret = -INF;
        if(L <= m) ret = max(ret, query(L, R, lson));
        if(R > m) ret = max(ret, query(L, R, rson));
        return ret;
    }
    int find_(int u, int v){
        int f1 = top[u], f2 = top[v];
        int tmp = -INF;
        while(f1 != f2){
    //        printf("!
    ");
            if(deep[f1] < deep[f2]){
                swap(f1, f2);
                swap(u, v);
            }
            tmp = max(tmp, query(p[f1], p[u], 1, n, 1));
            u = fa[f1]; f1 = top[u];
        }
        if(u == v){
            return tmp;
        }
        if(deep[u] > deep[v]){
            swap(u, v);
        }
    //    printf("* %d %d *
    ", u, v);
    //    printf("* %d %d *
    ", p[son[u]], p[v]);
        tmp = max(tmp, query(p[son[u]], p[v], 1, n, 1));
        return tmp;
    }
    int e[maxn][3];
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            init();
            scanf("%d", &n);
            int u, v, w;
            for(int i = 1; i < n; i++){
                scanf("%d%d%d", &u, &v, &w);
                e[i][0] = u;
                e[i][1] = v;
                e[i][2] = w;
                add_Edge(u, v);
                add_Edge(v, u);
            }
            dfs1(1, 0, 0);
            getpos(1, 1);
            build(1, n, 1);
    
    
    //        for(int i = 1; i <= n; i++){
    //            printf("i = %d pos = %d
    ", i, top[i]);
    //        }
            for(int i = 1; i < n; i++){
                u = e[i][0];
                v = e[i][1];
                if(deep[u] < deep[v]){
                    swap(u, v);
                    swap(e[i][0], e[i][1]);
                }
    //            printf("== %d %d ==
    ", p[u], p[v]);
                update(p[u], e[i][2], 1, n, 1);
    //            printf("bian = %d
    ", query(p[u], p[u], 1, n, 1));
            }
            char op[20];
            int x, y;
            while(scanf("%s", op)){
                if(op[0] == 'D') break;
                scanf("%d%d",&x, &y);
                if(op[0] == 'C'){
    //                printf("kao = %d
    ", p[e[x][0]]);
                    update(p[e[x][0]], y, 1, n, 1);
                }
                else{
                    printf("%d
    ", find_(x, y));
                }
            }
        }
        return 0;
    }
    /*
    1
    3
    1 2 1
    2 3 2
    QUERY 1 2
    CHANGE 1 3
    QUERY 1 2
    DONE
    */
    





  • 相关阅读:
    ☀【CSS3】形状
    ♫【MV*】
    ☀【布局】多栏布局 / 盒布局
    2017 无奈的模拟赛 1
    洛谷——P2093 零件分组
    洛谷——P1209 [USACO1.3]修理牛棚 Barn Repair
    洛谷——P2695 骑士的工作
    洛谷——P1330 封锁阳光大学
    python(16)- python内置函数
    MTK平台缩写
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7278570.html
Copyright © 2020-2023  润新知