HDU 5893 List wants to travel

HDU 5893 List wants to travel

树链剖分,边权

题目

给出2种操作

  1. 修改u到v的路径上的边的颜色为c
  2. 查询u到v的路径上有多少段颜色

思路

根bzoj2243差不多,就是把点权改成边权。把边权下放到深度大的点的点权。维护起来没有想的复杂。

先往重链头跳,跳完判断一下l是否跟r一样。一样说明汇合,不需要继续查了。否则查的时候要避开端点,可以查重儿子,看代码吧。

代码

树链剖分多组样例,记得把hson和depth数组清掉。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cstdlib>
#include<iostream>
#include<cmath>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define M(a,b) memset(a,b,sizeof(a))
using namespace std;
const int MAXN=50007;
typedef long long LL;

struct Edge
{
    int to, ne, val;
}G[MAXN*2];
int head[MAXN];
int Val[MAXN], Hson[MAXN], SonAmount[MAXN], Father[MAXN], Depth[MAXN];
int Dfsnum[MAXN], TreeValue[MAXN], TopOfHeavyChain[MAXN];
int dfscount, edgenum;

void AddEdge(int from, int to, int v)
{
    G[edgenum].to=to, G[edgenum].val=v, G[edgenum].ne=head[from];head[from]=edgenum++;
    G[edgenum].to=from, G[edgenum].val=v, G[edgenum].ne=head[to];head[to]=edgenum++;
}
void init()
{
    M(head, -1);M(G, 0);

    M(Hson, 0);M(Depth, 0);

    dfscount=0;edgenum=1;Val[1]=0;Father[1]=1;Depth[1]=1;
}
void dfs1(int n)
{
    SonAmount[n]=1;
    for(int i=head[n];~i;i=G[i].ne)
    {
        int to=G[i].to;
        if(Depth[to]) continue;
        Depth[to]=Depth[n]+1;

        Val[to]=G[i].val;//边权转化为点权

        Father[to]=n;
        dfs1(to);
        SonAmount[n]+=SonAmount[to];
        if(SonAmount[to]>SonAmount[Hson[n]]) Hson[n]=to;
    }
    return;
}
void dfs2(int n, int prev)
{
    Dfsnum[n]=++dfscount;
    TreeValue[dfscount]=Val[n];
    TopOfHeavyChain[n]=prev;
    if(!Hson[n]) return;
    dfs2(Hson[n], prev);
    for(int i=head[n];~i;i=G[i].ne)
    {
        int to=G[i].to;
        if(to==Hson[n]||to==Father[n]) continue;
        dfs2(to, to);
    }
}

struct Stree
{
    int lcol, rcol;
    int lazy;int num;
    Stree() { lcol=rcol=lazy=-1;num=0; }
    void init() { lcol=rcol=lazy=-1;num=0; }
}stree[MAXN<<2];
inline void pushup(int rt)
{
    stree[rt].num=stree[rt<<1].num+stree[rt<<1|1].num;
    if(stree[rt<<1].rcol==stree[rt<<1|1].lcol) stree[rt].num--;
    stree[rt].lcol=stree[rt<<1].lcol, stree[rt].rcol=stree[rt<<1|1].rcol;
}
inline void pushdown(int rt)
{
    if(stree[rt].lazy!=-1)
    {
        int c=stree[rt].lazy;stree[rt].lazy=-1;
        stree[rt<<1].lazy=stree[rt<<1|1].lazy=c;
        stree[rt<<1].num=stree[rt<<1|1].num=1;
        stree[rt<<1].lcol=stree[rt<<1|1].lcol=c;
        stree[rt<<1].rcol=stree[rt<<1|1].rcol=c;
    }
}
void build(int l, int r, int rt)
{
    stree[rt].init();
    if(l==r) { stree[rt].lcol=stree[rt].rcol=TreeValue[l];stree[rt].num=1;return; }
    int mid=(l+r)>>1;
    build(lson), build(rson);
    pushup(rt);
}
void update(int L, int R, int c, int l, int r, int rt)
{
    if(L<=l&&r<=R)
    {
        stree[rt].lcol=stree[rt].rcol=c;
        stree[rt].lazy=c;
        stree[rt].num=1;
        return;
    }
    pushdown(rt);
    int mid=(l+r)>>1;
    if(L<=mid) update(L, R, c, lson);
    if(mid<R) update(L, R, c, rson);
    pushup(rt);
}
Stree query(int L, int R, int l, int r, int rt)
{
    if(L<=l&&r<=R) return stree[rt];
    pushdown(rt);
    int mid=(l+r)>>1;
    if(R<=mid) return query(L, R, lson);
    else if(mid<L) return query(L, R, rson);
    else
    {
        Stree lres=query(L, R, lson);
        Stree rres=query(L, R, rson);
        Stree res;
        res.num=lres.num+rres.num-(lres.rcol==rres.lcol);
        res.lcol=lres.lcol, res.rcol=rres.rcol;
        return res;
    }
}

void solveup(int n)
{
    int l, r, c;scanf("%d%d%d", &l, &r, &c);
    int fl=TopOfHeavyChain[l], fr=TopOfHeavyChain[r];
    while(fl!=fr)
    {
        if(Depth[fl]>Depth[fr])
        {
            update(Dfsnum[fl], Dfsnum[l], c, 1, n, 1);
            l=Father[fl];fl=TopOfHeavyChain[l];
        }
        else
        {
            update(Dfsnum[fr], Dfsnum[r], c, 1, n, 1);
            r=Father[fr];fr=TopOfHeavyChain[r];
        }
    }
    if(l==r) return;
    if(Depth[l]>Depth[r])
        update(Dfsnum[Hson[r]], Dfsnum[l], c, 1, n, 1);
    else update(Dfsnum[Hson[l]], Dfsnum[r], c, 1, n, 1);
}
void solvequ(int n)
{
    int l, r;scanf("%d%d", &l, &r);
    //if(l==r) { printf("-1\n");return; }

    int fl=TopOfHeavyChain[l], fr=TopOfHeavyChain[r];
    int lcol=-1, rcol=-1, res=0;
    while(fl!=fr)
    {
        if(Depth[fl]>Depth[fr])
        {
            Stree lc=query(Dfsnum[fl], Dfsnum[l], 1, n, 1);
            res+=lc.num;
            if(lcol==lc.rcol) res--;
            lcol=lc.lcol;

            l=Father[fl];
            fl=TopOfHeavyChain[l];
        }
        else
        {

            Stree rc=query(Dfsnum[fr], Dfsnum[r], 1, n, 1);
            res+=rc.num;
            if(rcol==rc.rcol) res--;
            rcol=rc.lcol;

            r=Father[fr];
            fr=TopOfHeavyChain[r];
        }
    }
    if(l!=r)
    {
        if(Depth[l]>Depth[r])
        {
            Stree lc=query(Dfsnum[Hson[r]], Dfsnum[l], 1, n, 1);
            res+=lc.num;
            if(lcol==lc.rcol) res--;
            if(rcol==lc.lcol) res--;
        }
        else
        {
            Stree rc=query(Dfsnum[Hson[l]], Dfsnum[r], 1, n, 1);
            res+=rc.num;
            if(lcol==rc.lcol) res--;
            if(rcol==rc.rcol) res--;
        }
    }
    else
    {
        res-=(lcol==rcol);
    }
    printf("%d\n", res);
}
int main()
{
    //freopen("in.txt", "r", stdin);
    //freopen("ou1.txt", "w", stdout);
    int n, m;
    while(scanf("%d%d", &n, &m)==2)
    {
        init();
        for(int i=1;i<n;i++)
        {
            int u, v, c;scanf("%d%d%d", &u, &v, &c);
            AddEdge(u, v, c);
        }
        dfs1(1), dfs2(1, 1);build(1, n, 1);

        while(m--)
        {
            char s[10];
            scanf("%s", s);
            if(s[0]=='Q') solvequ(n);
            else solveup(n);
        }

    }

    //system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值