树链剖分模板

int head[N],hcnt;
int n,m,flag,L,R;
int son[N],siz[N],fa[N],top[N];
int id[N],tid,dep[N],posi[N];
LL seg[N<<2];
struct Node{int to,nxt;LL v;}node[N<<1];
struct Edge{int x,y;LL v;}edge[N];
void dfs1(int u,int f,int deep){
    fa[u]=f,dep[u]=deep,siz[u]=1;
    for(int i=head[u];~i;i=node[i].nxt){
        int e=node[i].to;if(e==f)continue;
        dfs1(e,u,deep+1);siz[u]+=siz[e];
        if(!son[u]||siz[son[u]]<siz[e])son[u]=e;
    }
}
void dfs2(int u,int tp){
    top[u]=tp,id[u]=++tid,posi[tid]=u;
    if(!son[u])return;dfs2(son[u],tp);
    for(int i=head[u];~i;i=node[i].nxt){
        int e=node[i].to;
        if(!id[e])dfs2(e,e);
    }
}
LL query(int rt,int l,int r){
    if(L<=l&&r<=R)return seg[rt];
    int mid=l+r>>1;LL temp=0;
    if(L<=mid)temp+=query(lson);
    if(R>mid) temp+=query(rson);
    return temp;
}
void update(int rt,int l,int r,LL v){
    if(l==r){seg[rt]=v;return;}
    int mid=l+r>>1;
    if(L<=mid)update(lson,v);
    else update(rson,v);
    seg[rt]=seg[rt<<1]+seg[rt<<1|1];
}
void lca(int x,int y){
    LL res=0;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        L=id[top[x]],R=id[x];
        res+=query(1,1,n);
        x=fa[top[x]];
    }
    if(dep[x]<dep[y])swap(x,y);
    L=id[y]+1,R=id[x];   ///维护边的时候注意L +1
    if(x!=y)res+=query(1,1,n);
    printf("%lld\n",res);
}
void init(){
    mst(head,-1);hcnt=tid=0;
    mst(siz,0);mst(son,0);mst(id,0);
}

 

posted @ 2016-10-06 10:57  Kurokey  阅读(233)  评论(0编辑  收藏  举报