HDU 3966 Aragorn's Story(树链剖分)

点权型树链剖分模板.


#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define MAXN 50100
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1

inline int RD(int &x)
{
        x = 0;
        char ch = getchar();
        while(!isdigit(ch)) { if(ch == '-') exit(0); ch = getchar(); if(ch == EOF) return 0; }
        while(isdigit(ch)) { x *= 10; x += ch - '0'; ch = getchar(); }
        return 1;
}

int sz[MAXN], dep[MAXN], son[MAXN], fa[MAXN], top[MAXN], w[MAXN], totw;
int a[MAXN], val[MAXN], n;

struct Edge
{
    int v, next;
}
ee[MAXN<<1];

int pre[MAXN], tote;

void init()
{
    memset(pre, 0, sizeof(pre));
    tote = dep[1] = 0;
    fa[1] = sz[1] = top[1] = w[1] = totw = 1;
}

void add_edge(int u, int v)
{
    tote++;
    ee[tote].v = v;
    ee[tote].next = pre[u];
    pre[u] = tote;
}

void dfs1(int i = 1)
{
    sz[i] = 1, son[i] = 0;
    for(int j = pre[i]; j; j = ee[j].next) if(ee[j].v != fa[i])
    {
        int v = ee[j].v;
        fa[v] = i;
        dep[v] = dep[i] + 1;
        dfs1(v);
        sz[i] += sz[v];
        if(sz[v] > sz[son[i]]) son[i] = v;
    }
}

void dfs2(int i = 1)
{
    if(son[i])
    {
        top[son[i]] = top[i];
        w[son[i]] = ++totw;
        dfs2(son[i]);
    }
    for(int j = pre[i]; j; j = ee[j].next) if(ee[j].v != fa[i] && ee[j].v != son[i])
    {
        int v = ee[j].v;
        w[v] = ++totw;
        dfs2(top[v] = v);
    }
}

int sum[MAXN << 2], cov[MAXN << 2];

void Build(int l = 1, int r = n, int rt = 1)
{
    cov[rt] = 0;
    if(l >= r)
    {
        sum[rt] = val[l];
        return ;
    }
    int m = (l + r) >> 1;
    Build(lson), Build(rson);
    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}

void Update(int L, int R, int add, int l = 1, int r = n, int rt = 1)
{
    if(L <= l && r <= R)
    {
        cov[rt] += add;
        sum[rt] += add;
        return ;
    }
    if(cov[rt])
    {
        cov[rt << 1] += cov[rt], cov[rt << 1 | 1] += cov[rt];
        sum[rt << 1] += cov[rt], sum[rt << 1 | 1] += cov[rt];
        cov[rt] = 0;
    }
    int m = (l + r) >> 1;
    if(L <= m) Update(L, R, add, lson);
    if(R  > m) Update(L, R, add, rson);
    sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}

int Query(int p, int l = 1, int r = n, int rt = 1)
{
    if(l >= r) return sum[rt];
    if(cov[rt])
    {
        cov[rt << 1] += cov[rt], cov[rt << 1 | 1] += cov[rt];
        sum[rt << 1] += cov[rt], sum[rt << 1 | 1] += cov[rt];
        cov[rt] = 0;
    }
    int m = (l + r) >> 1;
    int ret = 0;
    if(p <= m) ret += Query(p, lson);
    if(p  > m) ret += Query(p, rson);
    return ret;
}

char op[4];
int main()
{
//    freopen("A.in", "r", stdin);
    int m, p;
    while(RD(n))
    {
        RD(m), RD(p);
        init();
        for(int i = 1; i <= n; i++) RD(a[i]);
        for(int i = 1; i <= m; i++)
        {
            int u, v;
            RD(u), RD(v);
            add_edge(u, v);
            add_edge(v, u);
        }
        dfs1();
        dfs2();
        for(int i = 1; i <= n; i++) val[w[i]] = a[i];
//        for(int i = 1; i <= n; i++) cout << i << ": " << w[i] << ' ' << son[i] << ' ' << top[i] << ' ' << fa[i] << endl;
        Build();
        while(p--)
        {
            scanf("%s", op);
            if(op[0] == 'Q')
            {
                int x; RD(x);
                printf("%d\n", Query(w[x]));
            }
            else
            {
                int c1, c2, k;
                RD(c1), RD(c2), RD(k);
                if(op[0] == 'D') k = -k;
                while (top[c1] != top[c2])
                {
                    if (dep[top[c1]] < dep[top[c2]]) swap(c1, c2);
                    Update(w[top[c1]], w[c1], k);
                    c1 = fa[top[c1]];
                }
                if(dep[c1] < dep[c2]) swap(c1, c2);
                Update(w[c2], w[c1], k);
            }
        }
    }
    return 0;
}


你可能感兴趣的:(ACM,—,数据结构)