[bzoj2243][树链剖分]染色

【BZOJ 2243】染色 【树链剖分】 静态查错能力显著提升233,这次3分钟就查出bug#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> #include<cctype> using namespace std; #define N 100010 #define g() getchar() #define d 阅读详情

Description

给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作。

Input

第一行包含2个整数n和m,分别表示节点数和操作数; 第二行包含n个正整数表示n个节点的初始颜色 下面
行每行包含两个整数x和y,表示x和y之间有一条无向边。 下面 行每行描述一个操作: “C a b
c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c; “Q a
b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。

Output

对于每个询问操作,输出一行答案。

Sample Input

6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5

Sample Output

3
1
2

HINT

数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

题解

这个一眼就能看出来树剖吧。。
树剖的线段树的话维护一下这一段最左边的颜色,最右边的颜色,以及本身的颜色(不是纯色的话就为-1),打个lazy搞一下。。
修改我就不废话了大家都会吧。。
查询时x和y往上跳的时候分别维护两个值lasx和lasy,表示x,y当前查询到的最后一段上最上面那段的颜色。线段树问的时候维护两个值fir和tmp,表示当前查询这一段最下面的颜色和最上面的颜色。出来之后看一看fir和跳的这个las是不是相等,相等的话答案就要-1。之后las继承为tmp
如果你分不清我上面说的las的话请你看一看树剖跳轻重链的过程。那里会把lasx和lasy交换一下的
线段树查询的时候有一个小小的坑点。。上面说要维护一下这个段最左边和最右边的颜色,就是因为怕分开查询的时候中间连接的地方其实是一段,然后那里也是需要判一下的。。
实在听不下去我口胡的可以看一看代码。。我觉得可看性还是挺强的

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
struct node
{
    int x,y,next;
}a[211000];int len,last[111000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int fa[111000],dep[111000],tot[111000],son[111000],n,m;
void pre_tree_node(int x)
{
    son[x]=0;tot[x]=1;
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(y!=fa[x])
        {
            fa[y]=x;
            dep[y]=dep[x]+1;
            pre_tree_node(y);
            if(tot[son[x]]<tot[y])son[x]=y;
            tot[x]+=tot[y];
        }
    }
}
int ys[111000],top[111000],z;
void pre_tree_edge(int x,int tp)
{
    ys[x]=++z;top[x]=tp;
    if(son[x]!=0)pre_tree_edge(son[x],tp);
    for(int k=last[x];k;k=a[k].next)if(son[x]!=a[k].y && fa[x]!=a[k].y)pre_tree_edge(a[k].y,a[k].y);
}
struct trnode
{
    int lc,rc,l,r,c;
    int lef,rig;
    bool lazy;
}tr[410000];int trlen;
void bt(int l,int r)
{
    int now=++trlen;
    tr[now].l=l;tr[now].r=r;
    tr[now].lc=tr[now].rc=-1;tr[now].c=tr[now].lef=tr[now].rig=0;tr[now].lazy=false;
    if(l<r)
    {
        int mid=(l+r)/2;
        tr[now].lc=trlen+1;bt(l,mid);
        tr[now].rc=trlen+1;bt(mid+1,r);
    }
}
void upd(int x)
{
    int lc=tr[x].lc,rc=tr[x].rc;
    tr[lc].lazy=tr[rc].lazy=true;
    tr[lc].c=tr[rc].c=tr[x].c;
    tr[lc].lef=tr[lc].rig=tr[rc].lef=tr[rc].rig=tr[x].c;
    tr[x].lazy=false;
}
int lasx,lasy,fir,tmp,col[111000];
void change(int now,int l,int r,int c)
{
    if(tr[now].l==l && tr[now].r==r)
    {
        tr[now].c=tr[now].lef=tr[now].rig=c;
        tr[now].lazy=true;
        return ;
    }
    int lc=tr[now].lc,rc=tr[now].rc;
    int mid=(tr[now].l+tr[now].r)/2;
    if(tr[now].lazy)upd(now);
    if(r<=mid)change(lc,l,r,c);
    else if(mid+1<=l)change(rc,l,r,c);
    else change(lc,l,mid,c),change(rc,mid+1,r,c);
    if(tr[lc].c==tr[rc].c)tr[now].c=tr[lc].c;
    else tr[now].c=-1;
    tr[now].lef=tr[lc].lef;
    tr[now].rig=tr[rc].rig;
}
int findsum(int now,int l,int r,int lef,int rig)
{
    if(tr[now].c!=-1)
    {
        if(r>=rig)fir=tr[now].c;//问到了最下面的那个 
        if(l<=lef)tmp=tr[now].c;//最上面的那个 
        return 1;
    }
    int lc=tr[now].lc,rc=tr[now].rc;
    int mid=(tr[now].l+tr[now].r)/2;
    if(tr[now].lazy)upd(now);
    if(r<=mid)return findsum(lc,l,r,lef,rig);
    else if(mid+1<=l)return findsum(rc,l,r,lef,rig);
    else 
    {
        int retx=findsum(lc,l,mid,lef,rig),rety=findsum(rc,mid+1,r,lef,rig);
        if(tr[lc].rig==tr[rc].lef)return retx+rety-1;//中间其实是一段的情况 
        return retx+rety;
    }
}
void chmul(int x,int y,int c)
{
    int tx=top[x],ty=top[y];
    while(tx!=ty)
    {
        if(dep[ty]<dep[tx])swap(x,y),swap(tx,ty);
        change(1,ys[ty],ys[y],c);
        y=fa[ty];ty=top[y];
    }
    if(x==y){change(1,ys[x],ys[x],c);return ;}
    else
    {
        if(dep[x]>dep[y])swap(x,y);
        change(1,ys[x],ys[y],c);
        return ;    
    }
}
int sol(int x,int y)
{
    int tx=top[x],ty=top[y],ans=0;lasx=lasy=-999999999;
    while(tx!=ty)
    {
        if(dep[ty]<dep[tx])swap(x,y),swap(tx,ty),swap(lasx,lasy);
        ans+=findsum(1,ys[ty],ys[y],ys[ty],ys[y]);
        if(fir==lasy)ans--;lasy=tmp;
        y=fa[ty];ty=top[y];
    }
    if(x==y)
    {
        ans+=findsum(1,ys[x],ys[x],ys[x],ys[x]);
        if(fir==lasx)ans--;
        if(fir==lasy)ans--;
        return ans;
    }
    else
    {
        if(dep[x]>dep[y])swap(x,y),swap(lasx,lasy);
        ans+=findsum(1,ys[x],ys[y],ys[x],ys[y]);
        //x在上 y在下 
        if(fir==lasy)ans--;
        if(tmp==lasx)ans--;
        return ans;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&col[i]);
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        ins(x,y);ins(y,x);
    }
    fa[1]=0;dep[1]=0;pre_tree_node(1);
    z=0;pre_tree_edge(1,1);
    trlen=0;bt(1,z);
    for(int i=1;i<=n;i++)change(1,ys[i],ys[i],col[i]);
    while(m--)
    {
        char ss[10];int x,y,c;
        scanf("%s%d%d",ss+1,&x,&y);
        if(ss[1]=='C')
        {
            scanf("%d",&c);
            chmul(x,y,c);
        }
        else printf("%d\n",sol(x,y));
    }
    return 0;
}
FPGA学习之路—应用程序—原码二位乘法器及Verilog代码分析 FPGA学习之路——原码二位乘法器及Verilog代码分析 原理 原码乘法可以分为原码一位乘和原码二位乘,两者在实现规则上大同小异。原码一位乘每次判断乘数的最低位,对被乘数和部分积进行相应操作。而原码二位乘则是对乘数的低二位进行判断,并执行相关操作。 两位乘数的取值可以有四种可能组合,每种组合对应于以下操作: 00相当于0x,部分积Dresult右移2位,不进行其他运算; 01相当于1x,部分积D... 阅读详情

相关推荐

二维数字图像相关算法软件Ncorr的使用心得

二维开源软件Ncorr的DIC分析操作过程详解。

m0_72612723的博客 3万+

SDOI 2011 染色

SDOI 2011染色

Delat的博客 262

舵机操作手册

微型伺服马达原理与控制(中鸣) 1、微型伺服马达内部结构一个微型伺服马达内部包括了一个小型直流马达;一组变速齿轮组;一个反馈可调电位器;及一块电子控制板。其中,高速转动的直流马达提供了原始动力,带动变速(减速)齿轮组,使之产生高扭力的输出,齿轮组的变速比愈大,伺服马达的输出扭力也愈大,也就是说越能承受更大的重量,但转动的速度也愈低。 2、微行伺服马达的工作原理一个微型伺服马达是一个典型闭环反馈系统,其原理可由下图表示: 减速齿轮组由马达驱动,其终端(输出端)带动一个线性的比例电位器作位置检测,该电位器把

HEIMENGER的博客 3137

P3806 点分治1 (点分治模板题)

题目描述 给定一棵有n个点的树 询问树上距离为k的点对是否存在。 输入格式 n,m 接下来n-1条边a,b,c描述a到b有一条长度为c的路径 接下来m行每行询问一个K 输出格式 对于每个K每行输出一个答案,存在输出“AYE”,否则输出”NAY”(不包含引号) 输入输出样例 输入 #1 2 1 1 2 2 2 输出 #1 AYE 说明/提示 对于30%的数据n<=100 对于60%的数据n&l...

zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz 285

Fluent 中多相流模型全面解析

3.颗粒或液滴在连续相中的运动:若关注颗粒或液滴在连续相中的运动轨迹、分布规律以及与连续相的相互作用,如喷雾干燥、气力输送等过程,Eulerian-Lagrangian 模型则是最佳选择。Eulerian-Eulerian 模型可以准确模拟气体在固体颗粒中的流动情况,包括颗粒的流化状态、气体与颗粒之间的传热传质过程,为气固流化床的优化设计和操作提供依据。通过该模型,可以了解混合器内不同位置的混合程度、颗粒的运动轨迹以及液固相间的相互作用,从而改进混合器的结构和操作条件,提高混合效率。

khhdp的博客 3087

保姆级教程:用CellOracle 0.10.13分析你的单细胞数据,从GRN构建到基因扰动模拟

本文详细介绍了如何使用CellOracle 0.10.13进行单细胞数据分析,从基因调控网络(GRN)构建到基因扰动模拟的全流程。通过环境配置、数据准备、GRN构建和扰动模拟等步骤,帮助研究者高效预测细胞命运决定的分子机制,特别针对实际分析中的易错点提供解决方案。

weixin_42525005的博客 438

红黑树

一、前言 《二叉查找树全面详细介绍》介绍了二叉搜索树,它可以基本操作有:搜索(查找)、遍历、插入、删除等,其时间复杂度均为O(h),因此,如果搜索树的高度较低时,这些集合操作会执行得较快。然而,如果树的高度较高时,这些集合操作可能并不比在链表上执行得快。红黑树(red-black tree)是许多“平衡”搜索树中的一种,可以保证在最坏情况下基本动态集合操作的时间复杂度为O(Ign)。《二叉树平衡(有序数组创建)》、《二叉树平衡(DSW算法)》、《二叉树平衡(AVL树)》介绍了怎样构建平衡二叉树。 参考:

行走 352

第五节 Amesim《直动型溢流阀HCD建模》HCD5 学习资料

利用HCD原则创建直动型溢流阀的界面。这可能包括图形化表示直动型溢流阀的工作原理、操作方式和调节方法。这样的界面应当直观且易于理解,使用户能够轻松了解阀门的功能和使用方法。

m0_58052642的博客 1330

BZOJ 2243 染色 树链剖分+线段树

https://www.lydsy.com/JudgeOnline/problem.php?id=2243 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组成:“11”、“222”和“1”。 请你写一个程序依次完成这m个操作。 Inpu...

xiji333的博客 343

本地Qwen + ComfyUI 制作AI漫剧完整保姆级教程(2026年3月最新版)

本文介绍了一个零成本、本地化AI漫剧制作方案,整合Qwen大模型和ComfyUI工作流。Qwen负责剧本创作、分镜设计和提示词生成,ComfyUI处理图像生成、角色一致性保持和动态视频制作。该方案支持8GB显存设备运行(推荐12GB),包含详细安装指南和完整制作流程:从Ollama安装Qwen模型,到ComfyUI配置及必备节点安装,再到分镜生成、角色固定、批量出图和视频合成。文章还提供了常见问题解决方案和优化技巧,全流程1-2小时即可完成3分钟竖屏漫剧制作,适合新手和日更创作者。

posstos的博客 5551

14、5G物理层的灵活解决方案:广义频分复用(GFDM)

广义频分复用(GFDM)作为一种高度灵活的5G物理层多载波调制方案,能够满足多样化应用场景的需求,包括高吞吐量的比特管道通信、低功耗高连接数的物联网、超低延迟的触觉互联网以及广覆盖的无线区域网。通过参数化配置,GFDM可适配LTE资源网格,实现与现有系统的兼容与共存。其支持多种解调方式、干扰消除技术、OQAM映射及预编码机制,兼具低带外发射、高频谱效率和强鲁棒性。GFDM还能统一描述OFDM、FBMC、FTN等多种经典与先进波形,成为5G及未来通信系统中极具潜力的通用波形框架。

gold8的专栏 108

(noip 模拟 染色)<树形DP>

树形DP

SDFZspli的博客 676

uni-app - 实现全屏自适应且不变形背景大图,设置一张图片占满全屏(根据手机或电脑尺寸自动拉伸背景图像),用于页面是一张平铺的大图做背景的情况,全端兼容

uni-app,vue.js,微信小程序-设置背景图自适应手机屏幕尺寸,页面中的背景图片高度和宽度自适应,UNI-APP里如何设置背景图自适应手机屏幕尺寸,如何实现一个图片铺满整个页面,并且可以根据用户机型进行自动修正,自适应背景大图片官方教程,一个页面如何将图像放到背景上,纯CSS实现,设置背景图片占满全屏,3种CSS实现背景图片全屏铺满自适应的方式,uni-app中如何让图片不带高度的自适应,兼容uni-app全端,支持【纯】微信小程序项目使用,uni-app-实现全屏自适应且不变形背景大图

🏆 前端领域优质创作者 1万+

【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

【BZOJ2243】[SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。 请你写一个程序依次完成这m个操作。 Input 第一行包含2...

aodanchui1057的博客 159

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

[BZOJ2243][[SDOI2011]染色][树链剖分+线段树]

[BZOJ2243][[SDOI2011]染色][树链剖分+线段树]题目大意:给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。 请你写一个程序依次完成这m个操作。思路:树链剖分后在线段树上记录一下每个节点表示的区

羽裳 459

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

bzoj2243 染色 树链剖分

为了练手速我花了半个小时打完了这道题。。然后debug的时候就。。23333        首先如果是一个序列显然可以用线段树区间修改,维护段中的颜色数量,左右端点的颜色来做吧。        树上也一样,我们可以把树上的区间转化为dfs序列中若干个连续区间,然后用树链剖分使区间的个数(说白了就是一道树链剖分裸题)。 AC代码如下: #include #include #include #

lych的博客 592

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

bzoj 2243 染色 树链剖分 好题!

题意:中文题。 思路:很好的一道树链剖分。树剖后,线段树要记录左端点l,右端点r,左端点的颜色lc,右端点的颜色rc,区间成段更新的标记tag,区间 有多少颜色段。区间合并的时候要注意如果左子树的右端和右子树的左端颜色相同那么数量要减一。但是存在一个问题当前剖到 的链与上一次的链在相交的边缘可能颜色相同,如果颜色相同答案需要减一。所以统计答案的时候要记录下上一次剖到的链的左端 点的颜色,与

AC_kereo的专栏 3128

bzoj2243染色 树链剖分+线段树

2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 8230  Solved: 3073 [Submit][Status][Discuss] Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点

maxtir的博客 302

bzoj 2243 [SDOI2011]染色(树链剖分+线段树合并)

【bzoj2243】[SDOI2011]染色 2017年10月20日 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。 请你写一个程序依次完成这m个操作。 ...

weixin_30295091的博客 126

bzoj2243 染色 树链剖分 线段树

题目大意:C a b c 将a到b的路径上的点权覆盖为c Q a b 查询a到b的路径上有几段颜色 bzoj2243染色 树链剖分 写的不熟 注意细节#include<iostream> #include<cstdio> #define N 100005 using namespace std; struct E {int to,nxt;}edge[N*2]; struct T

yxr0105 491

BZOJ 2243: [SDOI2011]染色 树链剖分

Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。 请你写一个程序依次完成这m个操作。 Input 第一行包含2个整数n和m,分别表示节点数和操作数; 第二行包含n个正

I'm Growing 442

BZOJ-2243: [SDOI2011]染色-树链剖分

http://www.lydsy.com/JudgeOnline/problem.php?id=2243 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“

缺氧 927

BZOJ - 2243: [SDOI2011]染色 树链剖分

2243: [SDOI2011]染色 Time Limit:20 SecMemory Limit:512 MBSubmit:10456Solved:4013[Submit][Status][Discuss] Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点a到节点...

diangan7073的博客 182

bzoj 2243 树链剖分 染色

2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 3205  Solved: 1238 [Submit][Status][Discuss] Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点a到节点b路径上的颜

hero_ds的专栏 407

[SDOI2011] [BZOJ2243] 染色 - 树链剖分

2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 5001  Solved: 1860 [Submit][Status][Discuss] Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点

whzzt的博客 492

【BZOJ 2243】【SDOI 2011】染色【树链剖分】

学会树链剖分后的一道练手题。>_<Description给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。 请你写一个程序依次完成这m个操作。题解 若是你还不会树链剖分,请看这里  本题可以直接上 树链剖分+线段

cyclization的小栈 299
上一篇: [bzoj2242][exgcd][BSGS]计算器
下一篇: [bzoj1055][DP]玩具取名
Rose_max
博客等级 码龄10年 97粉丝 610原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值