bzoj2243 树链剖分

BZOJ 2243 浅谈树链剖分+线段树 世界真的很大 前几次考试有一次树链剖分当场写挂之后调了一下午 一直耿耿于怀,于是乎找一道树链剖分的题来练手 虽然代码量略大但是调试起来还是比较轻松,一个小错误卡了一会儿 没搞明白root根本没有赋值为什么还能过样例 一直RE加上return就A了看题先:description: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1、将节点a到节点b路径上所有点都染成颜色c; 阅读详情

Description

神犇家门口种了一棵苹果树。苹果树作为一棵树,当然是呈树状结构,每根树枝连接两个苹果,每个苹果都可以沿着一条由树枝构成的路径连到树根,而且这样的路径只存在一条。由于这棵苹果树是神犇种的,所以苹果都发生了变异,变成了各种各样的颜色。我们用一个到n之间的正整数来表示一种颜色。树上一共有n个苹果。每个苹果都被编了号码,号码为一个1到n之间的正整数。我们用0代表树根。只会有一个苹果直接根。

有许许多多的人来神犇家里膜拜神犇。可神犇可不是随便就能膜拜的。前来膜拜神犇的人需要正确回答一个问题,才能进屋膜拜神犇。这个问题就是,从树上编号为u的苹果出发,由树枝走到编号为v的苹果,路径上经过的苹果一共有多少种不同的颜色(包括苹果u和苹果v的颜色)?不过神犇注意到,有些来膜拜的人患有色盲症。具体地说,一个人可能会认为颜色a就是颜色b,那么他们在数苹果的颜色时,如果既出现了颜色a的苹果,又出现了颜色b的苹果,这个人只会算入颜色b,而不会把颜色a算进来。

神犇是一个好人,他不会强人所难,也就会接受由于色盲症导致的答案错误(当然答案在色盲环境下也必须是正确的)。不过这样神犇也就要更改他原先数颜色的程序了。虽然这对于神犇来说是小菜一碟,但是他想考验一下你。你能替神犇完成这项任务吗?

Input

输入第一行为两个整数n和m,分别代表树上苹果的个数和前来膜拜的人数。

接下来的一行包含n个数,第i个数代表编号为i的苹果的颜色Coli。

接下来有n行,每行包含两个数x和y,代表有一根树枝连接了苹果x和y(或者根和一个苹果)。

接下来有m行,每行包含四个整数u、v、a和b,代表这个人要数苹果u到苹果v的颜色种数,同时这个人认为颜色a就是颜色b。如果a=b=0,则代表这个人没有患色盲症。

Output

输出一共m行,每行仅包含一个整数,代表这个人应该数出的颜色种数。

Sample Input

5 3
1 1 3 3 2
0 1
1 2
1 3
2 4
3 5
1 4 0 0
1 4 1 3
1 4 1 2

Sample Output

2
1
2

HINT

0<=x,y,a,b<=N

N<=50000

1<=U,V,Coli<=N

距离上一次做这道题已经过了1个月了,不得不感慨当年还是太年轻。
这道题可以算作树链剖分的裸题,注意一下端点颜色相同的线段的合并就行了。

*第一次做题时一直没有想通query时swap(u,v)之后u所在的链和v所在的链的链顶颜色(cet[1]和cet[2])怎样保持正确性。其实很简单,在swap(u,v)后swap(cet[1],cet[2])就可以啦。
*swap的条件 if(dep[top[u]] < dep[top[v]] )

/**************************************************************
    Problem: 2243
    User: DD_D
    Language: C++
    Result: Accepted
    Time:5168 ms
    Memory:14548 kb
****************************************************************/


#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+5;
int n,m;
int col[N];
int to[2*N],nxt[2*N],head[N],etot;
int dep[N],son[N],size[N],fat[N];
int in[N],out[N],seq[N],idc,top[N];
int cet[5];
struct node{
    node *ls,*rs;
    int cof,cor,fg,num;
    void pushdown(){
        if(fg!=-1){
            //把它底下的要更新了
            ls->fg=rs->fg=fg;
            ls->cof=ls->cor=rs->cof=rs->cor=fg;
            ls->num=1;rs->num=1;
            fg=-1;
        }
    }
    void update(){
        cof=ls->cof;
        cor=rs->cor;
        if(ls->cor==rs->cof) num=ls->num+rs->num-1;
        else num=ls->num+rs->num;
    }
}pool[2*N+5],*tail=pool,*rt;
void adde(int u,int v)
{
    to[++etot]=v;
    nxt[etot]=head[u];
    head[u]=etot;
}
void dfs1(int u,int fa)//第一遍求siz fat dep 重儿子 
{
    size[u]=1; 
    fat[u]=fa;
    for(int i=head[u];i;i=nxt[i]){
        int v=to[i];
        if(v==fa) continue;
        dep[v]=dep[u]+1;
        dfs1(v,u);
        size[u]+=size[v];
        if(size[v]>size[son[u]]||son[u]==-1) son[u]=v;
    }
}
void dfs2(int u,int tp)//第二遍求dfs序 求dfs序时先进入重儿子  top[]
{
    in[u]=++idc;
    seq[idc]=u;
    top[u]=tp;
    if(son[u]!=-1) dfs2(son[u],tp);
    for(int i=head[u];i;i=nxt[i]){
        int v=to[i];
        if(v==son[u]||v==fat[u]) continue;
        dfs2(v,v);
    }
    out[u]=idc;
}
node *build(int lf,int rg)
{
    node *nd=++tail;
    if(lf==rg) {
        nd->cof=nd->cor=col[seq[lf]];
        nd->fg=-1;
        nd->num=1;
        return nd;
    }
    int mid=(lf+rg)>>1;
    nd->ls=build(lf,mid);
    nd->rs=build(mid+1,rg);
    nd->fg=-1;//!!!!!
    nd->update();
    return nd;
}
void modify(node *nd,int L,int R,int lf,int rg,int c)
{
    if(L<=lf&&rg<=R){
        nd->fg=c;
        nd->cof=c;
        nd->cor=c;
        nd->num=1;//!!!!
        return;
    }
    int mid=(lf+rg)>>1;
    nd->pushdown();
    if(L<=mid)   modify(nd->ls,L,R,lf,mid,c);
    if(R>mid) modify(nd->rs,L,R,mid+1,rg,c);
    nd->update();
}
void modify(int u,int v,int c)
{
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        modify(rt,in[top[u]],in[u],1,n,c);
        u=fat[top[u]];
    }
    if(dep[u]<dep[v]) swap(u,v);  
    modify(rt,in[v],in[u],1,n,c);
}
int query(node *nd,int L,int R,int lf,int rg)
{
    if(L<=lf&&rg<=R){
        if(L==lf) cet[0]=nd->cof;
        if(R==rg) cet[3]=nd->cor;
        return nd->num;
    }
    int mid=(lf+rg)>>1;
    nd->pushdown();
    int ans=0,r=-1,l=-1;
    if(L<=mid){
        ans+=query(nd->ls,L,R,lf,mid);
        l=nd->ls->cor;
    } 
    if(R>mid) {
        ans+=query(nd->rs,L,R,mid+1,rg);
        r=nd->rs->cof;
    }
    nd->update();

    if(l==r) ans--;
    return ans;
}
int query(int u,int v)
{
    int ans=0;
    memset(cet,-1,sizeof(cet));
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]]){
            swap(u,v);
            swap(cet[1],cet[2]);
        } 
        ans+=query(rt,in[top[u]],in[u],1,n);
        u=fat[top[u]];
        if(cet[3]==cet[1]) ans--;
        cet[1]=cet[0];
    }
    if(dep[u]<dep[v]) {
        swap(u,v);
        swap(cet[1],cet[2]);
    }
    ans+=query(rt,in[v],in[u],1,n);
    if(cet[1]==cet[3]) ans--;
    if(cet[2]==cet[0]) ans--;
    return ans;
}
int main()
{
    memset(son,-1,sizeof(son));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&col[i]);
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        adde(u,v),adde(v,u);
    }
    dfs1(1,1);
    dfs2(1,1);
    rt=build(1,idc);
    while(m--){
        char ch;
        int a,b,c;
        scanf("\n%c",&ch);
        if(ch=='C'){
            scanf("%d%d%d",&a,&b,&c);
            modify(a,b,c);
        }
        if(ch=='Q'){
            scanf("%d%d",&a,&b);
            printf("%d\n",query(a,b));
        }
    }
    return 0;
}

后记:突然发现博客里第一篇文章说的“想写但没过的树链剖分“就是这一道,缘分啊,真真妙不可言~

【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 阅读详情

相关推荐

单细胞专题(1) | 单细胞转录组研究样本准备指南(上)

单细胞RNA测序(scRNA-seq)是目前最前沿,能进行大规模实验的转录组研究技术,为理解细胞组成和动态生物学过程提供了很多新的见解。单细胞研究已经为我们理解发育过程,老化和疾病(如癌症)等提供了大量数据。在这里,小编主要就前期的样本准备与保存需注意问题给大家进行讲解,以备大家在不同的研究场景和研究背景下,走好单细胞转录组学研究的第一步。

bioyigene的博客 4232

BZOJ3757【树上莫队算法】

/* I will wait for you*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define make make_pair #define fi

Lethelody的专栏 695

Power BI常见问题篇1:无法打开文档

Power BI常见问题篇1:无法打开文档

weixin_48273257的博客 3305

bzoj 3757: 苹果树

Description     神犇家门口种了一棵苹果树。苹果树作为一棵树,当然是呈树状结构,每根树枝连接两个苹果,每个苹果都可以沿着一条由树枝构成的路径连到树根,而且这样的路径只存在一条。由于这棵苹果树是神犇种的,所以苹果都发生了变异,变成了各种各样的颜色。我们用一个到n之间的正整数来表示一种颜色。树上一共有n个苹果。每个苹果都被编了号码,号码为一个1到n之间的正整数。我们用0代表树根。只

lqybzx的专栏 991

从零到一:Bioconductor新手入门与R包安装实战

本文详细介绍了Bioconductor在生物信息学中的重要性及其R包安装实战指南。从环境准备到BiocManager的使用,再到常见问题排查,帮助新手快速掌握这一强大工具。特别推荐org.Hs.eg.db等核心工具包,助力基因注释和功能分析,提升研究效率。

weixin_29061041的博客 418

别让IO口保护二极管坑了你!实测讲解单片机电流倒灌的三种典型症状与防护

本文深入解析单片机电流倒灌的三大典型症状与防护方案,重点分析STM32等单片机在ADC采样异常、系统假死和通信速率异常中的表现。通过实测数据和电路设计建议,提供从基础二极管隔离到专业隔离器件的分级防护策略,帮助工程师有效预防和解决电流倒灌问题。

weixin_29280219的博客 347

树上莫队算法

江湖传闻,莫队算法能够解决一切区间查询问题。这样说来,莫队算法也能够解决一切树上路径查询问题,将树上操作转化为DFS序列上的区间操作即可。当然考虑到,树上路径在DFS序列中的性质,还要会求LCALCA。考虑上图中的树,其DFS序为其任意点对aa、bb之间的路径,具有如下性质,令lcalca为aa、bb的最近公共祖先: 若lcalca是aa、bb之一,则aa、bb之间的InIn时刻的区间或者OutOu

RBS的专栏 5875

项目风险管理全流程解析

按技术、资源、市场、外部环境等类型对风险进行分类,便于团队快速识别风险,提高风险管理效率,避免风险遗漏。项目结束后,总结实际发生的风险和应对效果,找出风险管理中的经验和教训,为后续项目提供参考。

qq_34062333的博客 1471

莫队算法(普通,带修,回滚,树上)

这是用来复习的博客,不太建议想要初学普通莫队的人看这篇博客,不过要是想快速复习一遍,这个博客可能比较适合你。 莫队算法(普通,带修,回滚) 莫队算法是一种通过对询问多关键字排序来降低时间复杂度的算法,当一些可离线题目满足 一个询问[l,r]的答案可以由[l-1,r]/[l+1,r]/[l,r-1]/[l,r+1]更新得到 时,可以考虑莫队算法。普通莫队不支持修改,不过如果是简单的修改可以用带修莫队/回滚莫队解决,至于树上问题则需要引入树上莫队,这里不做介绍(因为我也不会……)。实现简洁,应用面大,非常值得一

zixiangzhan的博客 2022

哨兵1号回波数据(L0级)提取与SAR成像(全网首发)

本文先展示提取出的回波结果,然后使用RD算法进行成像,展示成像结果,最后附上哨兵1号回波提取的MATLAB代码。

3797

高分SCI讨论部分必学AI写作套路!仅需五步结合GPT‑5辅助,让你的SCI论文更有说服力(附实用AI提示词)

对于很多写SCI论文的学术人来说,其实“讨论部分”才是最致命的,网上虽然有大量的写作技巧和模板提供参考,但往往让人眼花缭乱,还是不知道如何下手。即便是下手了,也很难兼顾学术性与可读性,实际上讨论部分的难点并不在于写,而在于你能研究结果说清楚。今天七哥教你借助GPT-5,用五步法结合精心设计的AI提示词,让你能在科学逻辑与语言表达上一次性解决“讨论部分”的结构、内容、润色和翻译问题,轻松写出符合高分SCI期刊要求的讨论段落。

智能AI让学术科研更容易 1330

【数据结构】树上莫队

树上莫队

conti123的博客 1097

【精品5万字图文详解】特征平台建设方案与最佳实践

关键词:特征工程、特征平台、特征存储、特征服务、机器学习、数据工程摘要:本文全面介绍了特征平台的建设方案与最佳实践,从特征工程的基本概念出发,深入剖析了特征平台的核心组件、架构设计和实现方法。文章通过生动的类比和实例,使读者能够轻松理解特征工程的重要性及特征平台如何解决企业在机器学习过程中面临的数据管理挑战。同时,详细探讨了主流开源特征平台的对比分析、系统设计要点、实际落地案例以及未来发展趋势,为企业构建高效特征平台提供了全面的指导和参考。想象一下,小明是一位热爱烹饪的小学生。有一天,他想做一道美味的菜肴送

AI天才研究院 954

【BZOJ2243 SDOI 2011 数颜色】树链剖分

BZOJ2243 没什么好说的 但是为什么我的树链剖分长度总是比别人长 看来该压行的时候还是要压行 /* if you can't see the repay Why not just work step by step rubbish is relaxed to ljq */ #include <cstdio> #include <cstring...

我是谁 --- 卡比兽 224

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【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

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

BZOJ 2243 染色 | 树链剖分模板题进阶版

BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了。 这道题要注意的是,无论是线段树上还是原树上,把两个区间的信息合并的时候,要注意中间相邻两个颜色是否相同。 这代码好长啊啊啊啊 幸好一次过了不然我估计永远也De不出来 #include <cstdio> #include ...

weixin_30346033的博客 95

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

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

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

羽裳 459

bzoj2243 染色 树链剖分

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

lych的博客 592

树链剖分模板题【spoj 375】【HDU 3966】【POJ 3237】【poj2763】【bzoj2243】

边权【spoj 375】 #include&lt;bits/stdc++.h&gt; using namespace std; typedef long long ll; const int maxn = 10010; struct Edge{ int to,next; }edge[maxn*2]; int head[maxn],tot; int top[maxn],fa[maxn...

纸箱xyr 214

bzoj 2243 染色 树链剖分 好题!

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

AC_kereo的专栏 3128

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

题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜色段数(仅考虑该区间) $lazy$表示延迟信息。 #include <bits/stdc++.h> using namespace std; #define ...

weixin_30375427的博客 84

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

BZOJ 2243 树链剖分

学习了一下树链剖分。 相关文章:http://blog.sina.com.cn/s/blog_7a1746820100wp67.html 这题差不多算是模板题了吧。 #include #include #include #include using namespace std; #define maxn 100005 struct SegTree { int l,r;

BehappyXiang的专栏 804

BZOJ2243 树链剖分

比较恶心的树链剖分的题,主要是在查询的时候注意链和链之间合并的时候去掉多余的分段。 /************************************************************** Problem: 2243 User: shllhsno1 Language: C++ Result: Accepted Time:5856

coding my life 646

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
上一篇: 9.24 NOIP模拟——“单”
下一篇: 9.27 数据结构noip模拟——不正常团伙
五彩蒟蒻DDD
博客等级 码龄10年 20粉丝 55原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值