POJ 2763 Housewife Wind(树链剖分:边权转化为点权)

传送门:

题意:

给n个点,q次询问,起点为s,输入n-1条待权边,每次询问有两种操作 0 y:求s -->y s转为y 的距离 操作:1 x y:将第x条边的权值改为y

题解:

利用一个bel[ ]:代表第i条边对应的点,因为是树形结构每个点只有一个父亲,所以可以通过这种关系将边权转化为点权,儿子节点代表的权值为,该儿子与父亲节点的边权。

AC代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
const ll maxn=2e5+5;
struct node
{
    ll to,id,w,nex;
} edge[maxn<<1];
ll bel[maxn],cnt,head[maxn],a[maxn];
ll top[maxn],sizx[maxn],son[maxn],pre[maxn];
ll dfn[maxn],deep[maxn],cnx;
void add(ll u,ll v,ll id,ll w)
{
    edge[cnt].to=v;
    edge[cnt].w=w;
    edge[cnt].id=id;
    edge[cnt].nex=head[u];
    head[u]=cnt++;
}
void dfs1(ll u,ll fa)
{
    pre[u]=fa;
    deep[u]=deep[fa]+1;
    sizx[u]=1;
    ll maxson=-1;
    for(ll i=head[u]; ~i; i=edge[i].nex)
    {
        ll v=edge[i].to;
        if(v!=fa)
        {
            bel[edge[i].id]=v;
            dfs1(v,u);
            sizx[u]+=sizx[v];
            if(maxson<sizx[v])
            {
                maxson=sizx[v];
                son[u]=v;
            }
        }
    }
}
void dfs2(ll u,ll t)
{
    dfn[u]=++cnx;
    top[u]=t;
    if(!son[u])
        return ;
    dfs2(son[u],t);
    for(ll i=head[u]; ~i; i=edge[i].nex)
    {
        ll v=edge[i].to;
        if(v!=son[u]&&v!=pre[u])
        {
            dfs2(v,v);
        }
    }
}
struct yzj
{
    ll l,r,dis;
} tr[maxn<<2];
void pushup(ll k)
{
    tr[k].dis=tr[k<<1].dis+tr[k<<1|1].dis;
}
void build(ll k,ll l,ll r)
{
    tr[k].l=l,tr[k].r=r;
    if(l==r)
    {
        tr[k].dis=a[l];
        return ;
    }
    ll mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    pushup(k);
}
void modify(ll k,ll pos,ll w)
{
    if(tr[k].l==tr[k].r)
    {
        tr[k].dis=w;
        return ;
    }
    ll mid=tr[k].l+tr[k].r>>1;
    if(mid>=pos)
    {
        modify(k<<1,pos,w);
    }
    else
        modify(k<<1|1,pos,w);
    pushup(k);
}
ll ask(ll k,ll l,ll r)
{
    if(tr[k].l>=l&&tr[k].r<=r)
    {
        return tr[k].dis;
    }
    ll mid=tr[k].l+tr[k].r>>1;
    if(mid>=r)
    {
        return ask(k<<1,l,r);
    }
    else if(mid<l)
    {
        ask(k<<1|1,l,r);
    }
    else
    {
        return ask(k<<1,l,mid)+ask(k<<1|1,mid+1,r);
    }
}
ll opt(ll x,ll y)
{
    ll res=0;
    while(top[x]!=top[y])
    {
        if(deep[top[x]]<deep[top[y]])
        {
            swap(x,y);
        }
        res+=ask(1,dfn[top[x]],dfn[x]);
        x=pre[top[x]];
    }
    if(x==y)
        return res;
    if(deep[x]>deep[y])
    {
        swap(x,y);
    }
    res+=ask(1,dfn[son[x]],dfn[y]);
    return res;
}
int main()
{
    memset(head,-1,sizeof(head));
    ll n,u,v,w,q,s;
    scanf("%lld %lld %lld",&n,&q,&s);
    for(ll i=1; i<n; i++)
    {
        scanf("%lld %lld %lld",&u,&v,&w);
        add(u,v,i,w);
        add(v,u,i,w);
    }
    dfs1(1,0);
    dfs2(1,1);
    for(ll i=1; i<=n; i++)
    {
        a[dfn[bel[i]]]=edge[i*2-1].w;
    }
    build(1,1,n);
    while(q--)
    {
        ll op,x,y,w;
        scanf("%lld",&op);
        if(op==0)
        {
            scanf("%lld",&y);
            printf("%lld\n",opt(s,y));
            s=y;
        }
        else
        {
            scanf("%lld %lld",&x,&w);
            modify(1,dfn[bel[x]],w);
        }
    }
}
发布了222 篇原创文章 · 获赞 16 · 访问量 9730

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/104345444
今日推荐