spoj 375

来源:互联网 发布:诺基亚6120c软件 编辑:程序博客网 时间:2024/05/01 06:01

树链剖分  此题是修改边的权值 

树链剖分部分 参考http://blog.sina.com.cn/s/blog_7a1746820100wp67.html

#include <cstdio>#include <cstdlib>#include <cmath>#include <set>#include <stack>#include <vector>#include <sstream>#include <cstring>#include <string>#include <map>#include <queue>#include <algorithm>#include <iostream>#define FFI freopen("in.txt", "r", stdin)#define maxn 20010#define INF 0x3f3f3f3f#define inf 10000000#define MOD 1000000007#define ULL unsigned long long#define LL long long#define _setm(houge) memset(houge, INF, sizeof(houge))#define _setf(houge) memset(houge, -1, sizeof(houge))#define _clear(houge) memset(houge, 0, sizeof(houge))using namespace std;struct node{    int l;    int r;    int max_val;    int setv;};node a[maxn<<2], p;void pushup(int rt){    a[rt].max_val = max(a[rt<<1].max_val, a[rt<<1|1].max_val);}void pushdown(int rt){    if(a[rt].setv != -1)    {        a[rt<<1].setv = a[rt<<1|1].setv = a[rt].setv;        a[rt<<1].max_val = a[rt<<1|1].max_val = a[rt].setv;        a[rt].setv = -1;    }}void build(int l, int r, int rt){    a[rt].max_val = 0;    a[rt].setv = -1;    a[rt].l = l;    a[rt].r = r;    if(l == r)        return;    int m = (l + r) >> 1;    build(l, m, rt<<1);    build(m+1, r, rt<<1|1);}void update(int x, int y, int rt, int v){    if(a[rt].l == x && a[rt].r == y)    {        a[rt].setv = v;        a[rt].max_val = v;        return;    }    pushdown(rt);    int m = (a[rt].l + a[rt].r) >> 1;    if(y <= m)        update(x, y, rt<<1, v);    else if(x > m)        update(x, y, rt<<1|1, v);    else    {        update(x, m, rt<<1, v);        update(m+1, y, rt<<1|1, v);    }    pushup(rt);}void query(int x, int y, int rt){    if(a[rt].l == x && a[rt].r == y) {        p.max_val = max(p.max_val, a[rt].max_val);        return;    }    pushdown(rt);    int m = (a[rt].l + a[rt].r) >> 1;    if(y <= m)        query(x, y, rt<<1);    else if(x > m)        query(x, y, rt<<1|1);    else {        query(x, m, rt<<1);        query(m+1, y, rt<<1|1);    }    pushup(rt);}struct Tedge{ int b, next; } e[maxn * 2];int n, z, edge, root;int d[maxn][3];int first[maxn], dep[maxn], w[maxn], fa[maxn], top[maxn], son[maxn], siz[maxn];void insert(int a, int b) {    e[++ edge].b = b;    e[edge].next = first[a];    first[a] = edge;}void dfs(int v) {    siz[v] = 1, son[v] = 0;    for(int i = first[v]; i > 0; i = e[i].next) {        if(e[i].b != fa[v]) {            fa[e[i].b] = v;            dep[e[i].b] = dep[v]+1;            dfs(e[i].b);            if(siz[e[i].b] > siz[son[v]]) son[v] = e[i].b;            siz[v] += siz[e[i].b];        }    }}void build_tree(int v, int tp) {    w[v] = ++ z, top[v] = tp;    if(son[v] != 0) build_tree(son[v], tp);    for(int i = first[v]; i > 0; i = e[i].next) {        if(e[i].b != fa[v] && e[i].b != son[v])            build_tree(e[i].b, e[i].b);    }}int _find(int va, int vb){    int f1 = top[va], f2 = top[vb], tmp = 0;    while (f1 != f2) {        if(dep[f1] < dep[f2]) {            swap(f1, f2);            swap(va, vb);        }        p.max_val = 0;        query(w[f1], w[va], 1);        tmp = max(tmp, p.max_val);        va = fa[f1];        f1 = top[va];     }     if(va == vb) return tmp;     if(dep[va] > dep[vb]) swap(va, vb);     p.max_val = 0;     query(w[son[va]], w[vb], 1);     return max(tmp, p.max_val);}int main(){    int t;    scanf("%d", &t);    while(t --) {        scanf("%d", &n);        root = (n+1)/2;        fa[root] = z = dep[root] = edge = 0;        _clear(siz);        _clear(first);        for(int i = 1; i < n; ++ i) {            int a, b, c;            scanf("%d%d%d", &a, &b, &c);            d[i][0] = a, d[i][1] = b, d[i][2] = c;            insert(a, b);            insert(b, a);        }        dfs(root);        build_tree(root, root);        //puts("121");        build(1, z, 1);        for(int i = 1; i < n; ++ i) {            if (dep[d[i][0]] > dep[d[i][1]]) swap(d[i][0], d[i][1]);            update(w[d[i][1]], w[d[i][1]], 1, d[i][2]);        }        char s[10];        while(scanf("%s", s) == 1 && s[0] != 'D') {            int a, b;            scanf("%d%d", &a, &b);            if(s[0] == 'Q') {                printf("%d\n", _find(a, b));            }            else {                update(w[d[a][1]], w[d[a][1]], 1, b);            }        }    }    return 0;}


0 0
原创粉丝点击