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;
}
原文地址:https://www.cnblogs.com/yigexigua/p/4079789.html