POJ2763-LCA在線算法+樹狀數組

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

const int NN=210000;

int n,en,c[NN],head[NN];
struct Edge{
    int v,w,next;
    Edge() {}
    Edge(int _v,int _w,int _next): v(_v),w(_w),next(_next) {}
} e[NN];

int index,bn,b[NN],f[NN],at[NN],fa[NN],num[NN],ctr[NN],dis[NN];
void dfs(int u)
{
    int tmp=++index;
    num[u]=index;
    b[++bn]=tmp; f[tmp]=u; at[u]=bn;
    for (int i=head[u]; i!=-1; i=e[i].next)
    {
        int v=e[i].v;
        if (fa[u]==v) continue;
        dis[v]=dis[u]+e[i].w;
        fa[v]=u;
        dfs(v);
        b[++bn]=tmp;
    }
    ctr[u]=index;
}

int dp[NN][30];
inline void RMQ_init(int n)
{
    for (int i=1; i<=n; i++) dp[i][0]=b[i];
    int m=floor(log(n*1.0)/log(2.0));
    for (int j=1; j<=m; j++)
      for (int i=1; i<=n-(1<<j)+1; i++)
          dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}

inline int RMQ(int l,int r)
{
    int k=floor(log(r-l+1)/log(2.0));
    return min(dp[l][k],dp[r-(1<<k)+1][k]);
}

inline int LCA(int a,int b)
{
    if (at[a]>at[b]) swap(a,b);
    return f[RMQ(at[a],at[b])];
}

inline int lowbit(int x)
{
    return x&(-x);
}

inline void update(int x,int w)
{
    if (x==0) return;
    while (x<=n)
    {
        c[x]+=w;
        x+=lowbit(x);
    }
}

inline int get_sum(int x)
{
    int ret=0;
    while (x)
    {
        ret+=c[x];
        x-=lowbit(x);
    }
    return ret;
}

inline int get(int x)
{
    return get_sum(num[x]);
}

int U[NN],V[NN],W[NN];
int main()
{
    int i,q,s,t,x,u,v,w,ans;

    while (~scanf("%d%d%d",&n,&q,&s))
    {
        en=0;
        for (i=1; i<=n; i++) head[i]=-1;

        for (i=1; i<n; i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            e[en]=Edge(v,w,head[u]); head[u]=en++;
            e[en]=Edge(u,w,head[v]); head[v]=en++;
            U[i]=u; V[i]=v; W[i]=w;
        }

        fa[1]=num[0]=dis[1]=index=bn=0;
        dfs(1);
        RMQ_init(bn);

        for (i=1; i<=q; i++)
        {
            scanf("%d",&w);
            if (w)
            {
                scanf("%d%d",&x,&v);
                if (fa[U[x]]==V[x]) u=U[x];
                else                u=V[x];
                update(num[u],v-W[x]);
                update(ctr[u]+1,W[x]-v);
                W[x]=v;
            }
            else
            {
                scanf("%d",&t);
                x=LCA(s,t);
                ans=dis[s]+get(s)+dis[t]+get(t)-2*(dis[x]+get(x));
                printf("%d\n",ans);
                s=t;
            }
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章