樹鏈剖分——模板整理__資料結構

來源:互聯網
上載者:User

可解決在給定的樹上的路徑問題。
複雜度:O( log2n log_2n)

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100015, maxe=200015;int n,Q,fir[maxn],nxt[maxe],son[maxe],w[maxe],tot;int hvy[maxn],sz[maxn],d[maxn],pre[maxn],w_pre[maxn],top[maxn],pos[maxn];struct node{ int L,R,sum; };struct segment{    node seg[maxn*4];    void maintain(int p){        seg[p].sum=seg[p<<1].sum+seg[p<<1|1].sum;    }    void build(int p,int L,int R,int* Arr){        seg[p].L=L; seg[p].R=R;        if(L==R){ seg[p].sum=*(Arr+L); return; }        int mid=(L+R)>>1;        build(p<<1,L,mid,Arr); build(p<<1|1,mid+1,R,Arr);        maintain(p);    }    void Updata(int p,int pos,int val){        if(pos<seg[p].L||seg[p].R<pos) return;        if(pos==seg[p].L&&seg[p].R==pos){ seg[p].sum=val; return; }        Updata(p<<1,pos,val); Updata(p<<1|1,pos,val);        maintain(p);     }    int Query(int p,int L,int R){        if(R<seg[p].L||seg[p].R<L) return 0;        if(L<=seg[p].L&&seg[p].R<=R) return seg[p].sum;        if(seg[p].L==seg[p].R) return 0;        return Query(p<<1,L,R)+Query(p<<1|1,L,R);    }} T;void dfs(int x){    sz[x]=1; hvy[x]=0;    for(int j=fir[x];j;j=nxt[j]) if(son[j]!=pre[x]){        pre[son[j]]=x; d[son[j]]=d[x]+1;        dfs(son[j]);        sz[x]+=sz[son[j]];         if(sz[son[j]]>sz[hvy[x]]) hvy[x]=son[j];    } else w_pre[x]=w[j];}int c[maxn];void build_chain(int x,int tp){    top[x]=tp; c[++c[0]]=w_pre[x]; pos[x]=c[0];    if(hvy[x]) build_chain(hvy[x],tp);    for(int j=fir[x];j;j=nxt[j]) if(son[j]!=pre[x])     if(son[j]!=hvy[x]) build_chain(son[j],son[j]);}int getsum(int x,int y){    int res=0;    while(top[x]!=top[y]){        if(d[top[x]]<d[top[y]]) swap(x,y);        res+=T.Query(1,pos[top[x]],pos[x]);        x=pre[top[x]];    }    if(x==y) return res;    if(d[x]>d[y]) swap(x,y);    return res+=T.Query(1,pos[x]+1,pos[y]);}void add(int x,int y,int z){    son[++tot]=y; w[tot]=z;    nxt[tot]=fir[x]; fir[x]=tot;}struct edge{ int x,y; } e[maxe];int now;int main(){    freopen("poj2763.in","r",stdin);    freopen("poj2763.out","w",stdout);    scanf("%d%d%d",&n,&Q,&now);    for(int i=1;i<=n-1;i++){        int z; scanf("%d%d%d",&e[i].x,&e[i].y,&z);        add(e[i].x,e[i].y,z); add(e[i].y,e[i].x,z);    }    dfs(1); build_chain(1,1); T.build(1,1,c[0],c);    while(Q--){        int pd; scanf("%d",&pd);        if(!pd){            int t; scanf("%d",&t);            printf("%d\n",getsum(now,t));             now=t;        } else{            int id,val; scanf("%d%d",&id,&val);            if(d[e[id].x]<d[e[id].y]) swap(e[id].x,e[id].y);            T.Updata(1,pos[e[id].x],val);        }    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.