[SDOI 2014] [JZOJ 3625] 旅行

35 篇文章 0 订阅
8 篇文章 0 订阅
本文介绍了一种通过离线大法优化树剖算法的方法,用于解决具有颜色限制条件的路径查询问题。具体而言,文章详细阐述了如何将不同颜色的操作进行排序,并使用线段树维护节点的权值和最大值,同时提供了实现步骤和代码片段,以帮助读者理解并应用这一解决方案。
摘要由CSDN通过智能技术生成

Description

一棵树,每个节点有权值和颜色。询问有一下几种:

  1. 询问从u到v的路径上与u相同颜色的节点的权值和(保证u与v颜色相同)
  2. 询问从u到v的路径上与u相同颜色的节点的权值的MAX(保证u与v颜色相同)
  3. 修改节点v的权值
  4. 修改节点v的颜色

Analysis

若不考虑颜色,那么这就是一个裸的链剖(链剖裸题)。

在线做法

由于还没有搞出来,留坑待填。

离线大法

首先,我们要高呼:离线大法好!离线大法好!离线大法好!
我们可以把相同颜色类型的操作排序在一起,操作原顺序为第二关键字。
把修改颜色操作看成是添加一个节点,到下一组颜色时为了不影响,应该再删除此节点。预处理也要看成是操作,也要拆成添加和删除。这样经过我们的转换后,各个颜色的操作之间就不影响了,变成了裸的链剖,就直接用线段树维护即可。

Key Code

    fo(i,1,n)
    {
        scanf("%d %d\n",&a[i],&c[i]);
        b[++Q].tp=2,b[Q].x=i,b[Q].y=a[i],b[Q].id=Q,b[Q].c=c[i];
    }
    fo(i,1,n-1)
    {
        scanf("%d %d\n",&u,&v);
        link(u,v),link(v,u);
    }
    dfs1(1,0,1);
    dfs2(1,0,1);
    char ch;
    fo(i,1,_)
    {
        scanf("%c%c %d %d\n",&ch,&ch,&x,&y);
        b[++Q].x=x,b[Q].y=y,b[Q].id=Q,b[Q].ps=i;
        if(ch=='S') b[Q].tp=0,bz[i]=1;
        else
        if(ch=='M') b[Q].tp=1,bz[i]=1;
        else
        if(ch=='W') b[Q].tp=2,a[x]=y;
        else
        {
            b[Q].tp=2,b[Q].c=y,b[Q].y=a[x];
            b[++Q].tp=2,b[Q].x=x,b[Q].y=0,b[Q].id=Q,b[Q].c=c[x];
            c[x]=y;
            continue;
        }
        b[Q].c=c[x];
    }
    fo(i,1,n) b[++Q].tp=2,b[Q].x=i,b[Q].y=0,b[Q].id=Q,b[Q].c=c[i];
    sort(b+1,b+Q+1,cmp);
    fo(i,1,Q)
    {
        if(b[i].tp<2) ans[b[i].ps]=solve(b[i].x,b[i].y,b[i].tp);
        else change(1,1,n,w[b[i].x],b[i].y);
    }
    fo(i,1,_)
        if(bz[i]) printf("%d\n",ans[i]);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值