FZU 2082 过路费(树链剖分,边权)

来源:互联网 发布:电玩游戏平台源码 编辑:程序博客网 时间:2024/04/30 16:54

树剖裸题

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int MAXN = 5e4+10;struct Edge{    int to,next;} edge[MAXN*2];int head[MAXN],tot;int top[MAXN];int fa[MAXN];int deep[MAXN];int num[MAXN];int p[MAXN];int fp[MAXN];int son[MAXN];int pos;long long sum[MAXN<<2];//segment treevoid init(){    tot = 0;    memset(head,-1,sizeof(head));    pos = 1;    memset(son,-1,sizeof(son));}void addedge(int u,int v){    edge[tot].to = v;    edge[tot].next = head[u];    head[u] = tot++;}void dfs1(int u, int pre, int dep){    deep[u] = dep;    fa[u] = pre;    num[u] = 1;    for(int i = head[u]; i != -1; i = edge[i].next)    {        int v = edge[i].to;        if(v == pre) continue;        dfs1(v,u,dep+1);        num[u] += num[v];        if(son[u] == -1 || num[v] > num[son[u]])            son[u] = v;    }}void getpos(int u, int sp){    top[u] = sp;    p[u] = pos++;    fp[p[u]] = u;    if(son[u] == -1) return;    getpos(son[u],sp);    for(int i = head[u]; i != -1; i = edge[i].next)    {        int v = edge[i].to;        if(v != son[u] && v != fa[u])            getpos(v,v);    }}#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int N;void update(int l, int r, int rt, int pos, int val){    if(l == r)    {        sum[rt] = val;        return;    }    int m = (l+r) >> 1;    if(pos <= m) update(lson,pos,val);    else update(rson,pos,val);    sum[rt] = sum[rt<<1] + sum[rt<<1|1];}int query(int L, int R, int l, int r, int rt){    if(l >= L && r <= R)        return sum[rt];    int m = (l+r) >> 1;    int ret = 0;    if(L <= m) ret += query(L,R,lson);    if(R > m) ret += query(L,R,rson);    return ret;}long long Calc(int u, int v){    int f1 = top[u],f2 = top[v];    long long tmp = 0;    while(f1 != f2)    {        if(deep[f1] < deep[f2])        {            swap(f1,f2);            swap(u,v);        }        tmp += query(p[f1],p[u],1,N,1);        u = fa[f1];        f1 = top[u];    }    if(u == v) return tmp;    if(deep[u] > deep[v]) swap(u,v);    return tmp + query(p[son[u]],p[v],1,N,1);}int e[MAXN][3];int n,m;int main(){    while(scanf("%d %d",&n,&m) != EOF)    {        init();        N = n;        memset(sum,0,sizeof(sum));        for(int i = 1; i < n; ++i)        {            scanf("%d %d %d",&e[i][0],&e[i][1],&e[i][2]);            addedge(e[i][0],e[i][1]);            addedge(e[i][1],e[i][0]);        }        dfs1(1,0,0);        getpos(1,1);        for(int i = 1; i < n; ++i)        {            if(deep[e[i][0]] > deep[e[i][1]])                swap(e[i][0],e[i][1]);            update(1,n,1,p[e[i][1]],e[i][2]);        }        int op,pos,val,u,v;        while(m--)        {            scanf("%d",&op);            if(op == 0)            {                scanf("%d %d",&pos,&val);                update(1,n,1,p[e[pos][1]],val);            }            else            {                scanf("%d %d",&u,&v);                printf("%I64d\n",Calc(u,v));            }        }    }    return 0;}
原创粉丝点击