poj2763

树状数组记录各点到根的距离。边值变化时,深度大的点的bg[]树状数组中增加,fn[]+1减。树状数组中x位置变化影响的是>=x的数。这样bg[]+,fn[]+1 减,这样就能消除影响。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
//#include <unordered_set>
#define mkp make_pair
#define err cout<<"here"<<endl
using namespace std;
const double EPS=1e-12;
typedef long long lon;
typedef unsigned long long ull;
typedef map<ull,int>::iterator IT;
const lon SZ=100010,SSZ=1000010,APB=20,mod=100000,one=97;
const lon INF=0x7FFFFFFF;
lon n,bg[SZ],fn[SZ],cnt,dp[SZ][APB];
int dst[SZ],sum[SZ],dep[SZ];
struct nd{
    lon to,wt;
    nd(lon a=0,lon b=0):to(a),wt(b){}
};
int head[SZ],nex[SSZ],to[SSZ],wt[SSZ];
int tot=-1;
void add_edge(int u,int v,int w)
{
    ++tot;
    nex[tot]=head[u];
    head[u]=tot;
    to[tot]=v,wt[tot]=w;
}
struct pt{
    int u,v,w;
    pt(int a=0,int b=0,int c=0):u(a),v(b),w(c){}
};
pt arr[SZ];

void dfs1(int x,int p,int y,int d)
{
    bg[x]=++cnt;
    if(p!=-1)dp[x][0]=p;
    dst[x]=y,dep[x]=d;
    for(int i=1;i<APB;++i)
    {
        dp[x][i]=dp[dp[x][i-1]][i-1];
    }
    for(int i=head[x];i!=-1;i=nex[i])
    {
        int t=to[i];
        int w=wt[i];
        if(t!=p)
        {
            dfs1(t,x,y+w,d+1);
        }
    }
    fn[x]=cnt;
}

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

void add(int x,int val)
{
    if(x<=0)return;
    for(;x<SZ;x+=lowbit(x))
    {
        sum[x]+=val;
    }
}

int qry(int x)
{
    int res=0;
    for(;x>0;x-=lowbit(x))
    {
        res+=sum[x];
    }
    return res;
}

int lca(int x,int y)
{
    if(dep[x]<dep[y])swap(x,y);
    for(int i=APB-1;i>=0;--i)
    {
        if(dep[dp[x][i]]>=dep[y])
        {
            x=dp[x][i];
        }
    }
    if(x==y)return x;
    for(int i=APB-1;i>=0;--i)
    {
        if(dp[x][i]!=dp[y][i])
        {
            x=dp[x][i];
            y=dp[y][i];
        }
    }
    return dp[x][0];
}

void init()
{
    int qnum,cur;
    cin>>n>>qnum>>cur;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=n-1;++i)
    {
        int a,b,c;
        //cin>>a>>b>>c;
        scanf("%d%d%d",&a,&b,&c);
        add_edge(a,b,c);
        add_edge(b,a,c);
        arr[i]=pt(a,b,c);
    }
    dfs1(1,-1,0,1);
//    for(int i=1;i<=n-1;++i)
//    {
//        int u=arr[i].u;
//        int v=arr[i].v;
//        int w=arr[i].w;
//        if(dep[u]<dep[v])swap(u,v);
//        add(bg[u],w);
//        add(fn[u]+1,-w);
//    }
    for(int i=1;i<=n;++i)
    {
        add(bg[i],dst[i]);
        add(bg[i]+1,-dst[i]);
        //cout<<"i: "<<i<<" "<<bg[i]<<" "<<dst[i]<<endl;
        //if(bg[i]!=1)add(bg[i]-1,-dst[i]);
    }
    for(int i=1;i<=qnum;++i)
    {
        int type;
        //cin>>type;
        scanf("%d",&type);
        if(!type)
        {
            int pos;
            //cin>>pos;
            scanf("%d",&pos);
            int res=0;
            //pos=3;
            res+=qry(bg[pos]);//-qry(bg[pos]-1);
            res+=qry(bg[cur]);//-qry(bg[cur]-1);
            //cout<<"cur: "<<cur<<endl;
            int tmp=bg[lca(pos,cur)];
            res-=2*qry(tmp);//2*(qry(tmp)-qry(tmp-1));
            //cout<<res<<endl;
            printf("%d\n",res);
            cur=pos;
        }
        else
        {
            int id,val;
            //cin>>id>>val;
            scanf("%d%d",&id,&val);
            int u=arr[id].u;
            int v=arr[id].v;
            int lw=dep[u]>dep[v]?u:v;
            int delta=val-arr[id].w;
            add(fn[lw]+1,-delta);
            add(bg[lw],delta);
            arr[id].w=val;
        }
    }
}

void work()
{
    
}

void release()
{    
    
}

int main()
{
    //std::ios::sync_with_stdio(0);
    //freopen("d:\\1.txt","r",stdin);
    lon casenum;
    //cin>>casenum;
    //cout<<casenum<<endl;
    //for(lon time=1;time<=casenum;++time)
    //for(lon time=1;cin>>m>>n;++time)
    {
        init();
        work();
        release();
    }
    return 0;
}

 

posted @ 2019-05-20 11:06  degvx  阅读(138)  评论(0)    收藏  举报