hdu 5044 Tree 树链剖分

来源:互联网 发布:.lol域名备案 编辑:程序博客网 时间:2024/04/27 23:55

贴下模板,,,,,

#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;}


0 0
原创粉丝点击