poj2763树链剖分边权+区间和

自己写的比原来的板子常数小了不少嘻嘻,边权处理起来比点权要复杂一下

由于根节点没有被映射的边,其被访问到的顺序是0,直接排除在线段树外

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 100005
struct Edge{
    int to,next;
}edge[maxn<<1];
int head[maxn],tot,e[maxn][3];
int fa[maxn],son[maxn],num[maxn],deep[maxn];
int top[maxn],p[maxn],fp[maxn],pos;
inline 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){
    fa[u]=pre;deep[u]=dep;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[son[u]]<num[v]) 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==fa[u] || v==son[u]) continue;
        getpos(v,v);
    }
}

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[maxn<<2];
inline void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
void update(int pos,int val,int l,int r,int rt){
    if(l==r) {sum[rt]=val;return;}
    int m=l+r>>1;
    if(pos<=m) update(pos,val,lson);
    else update(pos,val,rson);
    pushup(rt);
}
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,res=0;
    if(L<=m) res+=query(L,R,lson);
    if(R>m) res+=query(L,R,rson);
    return res;
}
int query2(int u,int v){
    int f1=top[u],f2=top[v],res=0;
    while(f1!=f2){
        if(deep[f1]<deep[f2]) swap(f1,f2),swap(u,v);
        res+=query(p[f1],p[u],1,pos,1);
        u=fa[f1],f1=top[u];
    }
    if(u==v) return res;
    if(deep[u]>deep[v]) swap(u,v);
    res+=query(p[son[u]],p[v],1,pos,1);
    return res;
}
void init(){
    tot=pos=0;
    memset(head,-1,sizeof head);
    memset(son,-1,sizeof head);
    memset(sum,0,sizeof sum);
}
int main(){
    int n,q,now,op,a,b;
    while(scanf("%d%d%d",&n,&q,&now)!=EOF){
        init();
        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(p[e[i][1]],e[i][2],1,pos,1);
        }
        while(q--){
            scanf("%d",&op);
            if(op==0) {scanf("%d",&a);printf("%d\n",query2(now,a));now=a;}
            else {scanf("%d%d",&a,&b);update(p[e[a][1]],b,1,pos,1);}//第a条边改为b
        }
    }
    return 0;
}

 

posted on 2018-11-29 22:17  zsben  阅读(118)  评论(0编辑  收藏  举报

导航