• light1348Aladdin and the Return Journey树链剖分


    点更新模版题,线段树 建树的时候没写更新,交了几十次吧。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<vector>
    #include<stdlib.h>
    using namespace std;
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    typedef long long LL;
    const int maxn = 333333;
    int son[maxn], size[maxn], head[maxn], deep[maxn], pos[maxn], vis[maxn], top[maxn];
    int father[maxn];
    int val[maxn];
    int sum[maxn << 2];
    struct Node
    {
        int next; int to;
    }e[maxn * 2];
    int len, z;
    
    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;
            deep[cc] = deep[x]+1;
            father[cc] = x;
            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 add(int from, int to)
    {
        e[len].to = to;
        e[len].next = head[from];
        head[from] = len++;
    }
    
    
    void up(int rt)
    {
        sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    }
    void build(int l, int r, int rt)
    {
        if (l == r){
           // printf("%d %d
    ",l,val[vis[l]]);
            sum[rt] = val[vis[l]]; return;
        }
        int mid = (l + r) >> 1;
        build(lson);
        build(rson);
        up(rt);
    }
    
    void update(int key, int ans, int l, int r, int rt)
    {
        if (l == r){
            sum[rt] = ans; return;
        }
        int mid = (l + r) >> 1;
        if (key <= mid) update(key, ans, lson);
        else update(key, ans, rson);
        up(rt);
    }
    
    int ask(int L, int R, int l, int r, int rt)
    {
        if (L <= l&&r <= R) return sum[rt];
        int mid = (l + r) >> 1;
        int ans = 0;
        if (L <= mid) ans += ask(L, R, lson);
        if (R > mid) ans += ask(L, R, rson);
        return ans;
    }
    
    int gao(int x, int y)
    {
        int ans = 0;
        int fx = top[x]; int fy = top[y];
        while (fx != fy){
            if (deep[fx] < deep[fy]){
                swap(x, y); swap(fx, fy);
            }
            ans += ask(pos[fx], pos[x], 1, z, 1);
            x = father[fx]; fx = top[x];
        }
        if (deep[x]>deep[y]) swap(x, y);
        ans += ask(pos[x], pos[y], 1, z, 1);
        return ans;
    }
    
    int main()
    {
        int t;
        int n;
        int a, b, c;
        int Icase = 0;
        scanf("%d",&t);
        int q;
        while (t--){
            scanf("%d",&n);
            len = 0; z = 0; memset(head, -1, sizeof(head));
    
            for (int i = 1; i <= n; i++){
                scanf("%d", &val[i]);
            }
            for (int i = 1; i < n; i++){
                scanf("%d%d", &a, &b); add(a + 1, b + 1); add(b + 1, a + 1);
            }
            init(1);dfs(1,1);build(1,z,1);
            scanf("%d",&q);
            printf("Case %d:
    ", ++Icase);
            while (q--){
                scanf("%d%d%d", &a, &b, &c);
                if (a == 0){
                    printf("%d
    ",gao(b+1,c+1));
                }
                else{
                    update(pos[b + 1], c, 1, z, 1);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    [分享] Knockout.js 体验之旅
    [分享] 用NodeJs做一个小爬虫,附源码!
    [分享] 纯CSS完美实现垂直水平居中的6种方式
    [分享] 来,做一个问卷调查(有抽奖!)
    除非你是BAT,前端开发中最好少造轮子
    [分享] 微信支付中商户对个人用户付款案例
    30分钟做一个二维码名片应用,有源码!
    【分享】WeX5的正确打开方式(7)——数据组件详解
    基于phonegap,html5,ratchet,handlebars等技术的微表情APP
    html5实现web app摇一摇换歌
  • 原文地址:https://www.cnblogs.com/yigexigua/p/4079789.html
Copyright © 2020-2023  润新知