hdu 5044 Tree 树链剖分

贴下模板,,,,,

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <stack>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <ctime>
#include <cstdlib>
using namespace std;

#define mxn 100020
#define mxe 200020
#define N 10020
#define M 2000020
#define mod 2147483647
#define LL long long
#define inf 0x3f3f3f3f
#define vi vector<int>
#define PB push_back
#define MP make_pair
#define pii pair<int, int>
#pragma comment(linker,"/STACK:1024000000,1024000000")
#define ls (i << 1)
#define rs (ls | 1)
#define md ((ll + rr) >> 1)


int fst[mxn], nxt[mxe], to[mxe], e;
void init() {
    memset(fst, -1, sizeof fst);
    e = 0;
}
void add(int u, int v) {
    to[e] = v, nxt[e] = fst[u], fst[u] = e++;
}
int adj[mxn];
int n, m;
int dep[mxn], sz[mxn], son[mxn], fa[mxn];
int dc, tid[mxn], lab[mxn];
LL cntE[mxn<<2], cntN[mxn<<2];
int tp[mxn];

void dfsH(int u, int p, int d) {
    dep[u] = d, fa[u] = p;
    son[u] = 0, sz[u] = 1;
    int mx = 0;
    for(int i = fst[u]; ~i; i = nxt[i]) {
        int v = to[i];
        if(v == p) continue;
        adj[i>>1] = v;
        dfsH(v, u, d + 1);
        sz[u] += sz[v];
        if(sz[v] > mx)
            mx = sz[v], son[u] = v;
    }
}
void dfsC(int u, int anc) {
    tid[u] = ++dc;
    lab[dc] = u;
    tp[u] = anc;
    if(son[u])
        dfsC(son[u], anc);
    for(int i = fst[u]; ~i; i = nxt[i]) {
        int v = to[i];
        if(v == fa[u] || v == son[u]) continue;
        dfsC(v, v);
    }
}
void update(int l, int r, int k, int t, int ll, int rr, int i) {
    if(ll == l && rr == r) {
        if(t == 0)
            cntN[i] += k;
        else
            cntE[i] += k;
        return;
    }
    if(r <= md)
        update(l, r, k, t, ll, md, ls);
    else if(l > md)
        update(l, r, k, t, md + 1, rr, rs);
    else
        update(l, md, k, t, ll, md, ls),
        update(md + 1, r, k, t, md + 1, rr, rs);
}
void f(int t, int u, int v, int k) {
    while(tp[u] != tp[v]) {
        if(dep[tp[u]] > dep[tp[v]]) swap(u, v);
        update(tid[tp[v]], tid[v], k, t, 1, n, 1);
        v = fa[tp[v]];
    }
    if(dep[u] > dep[v]) swap(u, v);
    if(t == 0)
        update(tid[u], tid[v], k, t, 1, n, 1);
    else
        if(u != v)
            update(tid[u] + 1,tid[v], k, t, 1, n, 1);
}
LL query(int x, int t, int ll, int rr, int i) {
    if(ll == rr) {
        if(t == 0)
            return cntN[i];
        else
            return cntE[i];
    }
    LL ret = 0;
    if(t == 0) ret += cntN[i];
    else ret += cntE[i];
    if(x <= md) ret += query(x, t, ll, md, ls);
    else ret += query(x, t, md + 1, rr, rs);
    return ret;
}
void build(int ll, int rr, int i) {
    cntE[i] = cntN[i] = 0;
    if(ll == rr) return;
    build(ll, md, ls), build(md + 1, rr, rs);
}
int readint() {
    char c;
    while((c = getchar()) && !(c >= '0' && c <= '9'));
    int ret = c - '0';
    while((c = getchar()) && c >= '0' && c <= '9')
        ret = ret * 10 + c - '0';
    return ret;
}
int main() {
    int cas, kk = 0;
    scanf("%d", &cas);
    while(cas--) {
        init();
        n = readint();
        m = readint();
        for(int i = 1; i < n; ++i) {
            int u, v;
            u = readint(), v = readint();
            add(u, v), add(v, u);
        }
        dfsH(1, -1, 0);
        dc = 0;
        dfsC(1, 1);
        build(1, n, 1);
        while(m--) {
            char s[6];
            int u, v, k;
            scanf("%s", s);
            u = readint();
            v = readint();
            k = readint();
            f(s[3] - '1', u, v, k);
        }
        printf("Case #%d:\n", ++kk);
        for(int i = 1; i <= n; ++i) {
            printf("%I64d", query(tid[i], 0, 1, n, 1));
            putchar(i == n? '\n': ' ');
        }
        for(int i = 0; i < n - 1; ++i) {
            printf("%I64d", query(tid[adj[i]], 1, 1, n, 1));
            putchar(i == n - 2? '\n': ' ');
        }
        if(n == 1)
            puts("");
    }
    return 0;
}


你可能感兴趣的:(树链剖分)