题目链接

线段树维护区间连续段个数即可。设lc为区间左端点颜色,rc为区间右端点颜色,则合并两区间的时候,如果左区间右端点和右区间左端点颜色相同,则连续段个数-1。

在树链上的区间合并可以定义一个结构体作为线段,分成左右两条链暴力合并。也可以考虑到树上的路径中每两个树链“断开”的地方必然有一个结点是另一个结点的祖先,因此如果top[u]的颜色与fa[top[u]]的颜色相同时答案-1即可。

树剖和线段树结合真容易把人搞晕啊,什么时候要用l,r,什么时候要用u,什么时候要用dfn[u],一定要分清楚~~

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+,inf=0x3f3f3f3f;
int hd[N],ne,n,k,fa[N],son[N],siz[N],dep[N],top[N],dfn[N],rnk[N],tot,a[N],cnt[N<<],mk[N<<],lc[N<<],rc[N<<];
struct E {int v,nxt;} e[N<<];
void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;}
void dfs1(int u,int f,int d) {
fa[u]=f,fa[u]=f,siz[u]=,dep[u]=d;
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==fa[u])continue;
dfs1(v,u,d+),siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs2(int u,int tp) {
top[u]=tp,dfn[u]=++tot,rnk[dfn[u]]=u;
if(!son[u])return;
dfs2(son[u],top[u]);
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((l+r)>>1)
void pu(int u) {lc[u]=lc[ls],rc[u]=rc[rs],cnt[u]=cnt[ls]+cnt[rs]; if(rc[ls]==lc[rs])cnt[u]--;}
void pd(int u) {if(mk[u])lc[u]=rc[u]=mk[u],cnt[u]=,mk[ls]=mk[rs]=mk[u],mk[u]=;}
void build(int u=,int l=,int r=tot) {
if(l==r) {lc[u]=rc[u]=a[rnk[l]],cnt[u]=; return;}
build(ls,l,mid),build(rs,mid+,r),pu(u);
}
void upd(int L,int R,int x,int u=,int l=,int r=tot) {
pd(u);
if(l>=L&&r<=R) {mk[u]=x,pd(u); return;}
if(l>R||r<L)return;
upd(L,R,x,ls,l,mid),upd(L,R,x,rs,mid+,r),pu(u);
}
int getcol(int p,int u=,int l=,int r=tot) {
pd(u);
if(l==r)return lc[u];
return p<=mid?getcol(p,ls,l,mid):getcol(p,rs,mid+,r);
}
int qry(int L,int R,int u=,int l=,int r=tot) {
pd(u);
if(l>=L&&r<=R)return cnt[u];
if(l>R||r<L)return ;
int t1=qry(L,R,ls,l,mid),t2=qry(L,R,rs,mid+,r);
int ret=t1+t2;
if(t1&&t2&&rc[ls]==lc[rs])ret--;
return ret;
}
void change(int u,int v,int x) {
for(; top[u]!=top[v]; u=fa[top[u]]) {
if(dep[top[u]]<dep[top[v]])swap(u,v);
upd(dfn[top[u]],dfn[u],x);
}
if(dep[u]<dep[v])swap(u,v);
upd(dfn[v],dfn[u],x);
}
int ask(int u,int v) {
int ret=;
for(; top[u]!=top[v]; u=fa[top[u]]) {
if(dep[top[u]]<dep[top[v]])swap(u,v);
ret+=qry(dfn[top[u]],dfn[u]);
if(getcol(dfn[top[u]])==getcol(dfn[fa[top[u]]]))ret--;
}
if(dep[u]<dep[v])swap(u,v);
ret+=qry(dfn[v],dfn[u]);
return ret;
}
int main() {
memset(hd,-,sizeof hd),ne=;
scanf("%d%d",&n,&k);
for(int i=; i<=n; ++i)scanf("%d",&a[i]),a[i]++;
for(int i=; i<n; ++i) {
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
tot=,dfs1(,,),dfs2(,),build();
while(k--) {
char ch;
int a,b,c;
scanf(" %c%d%d",&ch,&a,&b);
if(ch=='Q')printf("%d\n",ask(a,b));
else scanf("%d",&c),c++,change(a,b,c);
}
return ;
}

BZOJ - 2243 染色 (树链剖分+线段树+区间合并)的更多相关文章

  1. 2243: [SDOI2011]染色 树链剖分+线段树染色

    给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组 ...

  2. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

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

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  4. B20J_2243_[SDOI2011]染色_树链剖分+线段树

    B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...

  5. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  6. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  7. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  8. bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2852  Solved: 1668[Submit][Sta ...

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

    题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...

  10. bzoj 2157: 旅游【树链剖分+线段树】

    裸的树链剖分+线段树 但是要注意一个地方--我WA了好几次才发现取完相反数之后max值和min值是要交换的-- #include<iostream> #include<cstdio& ...

随机推荐

  1. iOS JS 和 OC交互 / JS 和 native 相互调用

    现在app 上越来越多需求是通过UIWebView 来展示html 或者 html5的内容, js 和 native OC代码交互 就非常常见了. js 调用 native  OC代码 第一种机制 ( ...

  2. 计算机网络概述 传输层 TCP拥塞控制

    TCP拥塞控制 计算机网络中的带宽.交换结点中的缓存和处理机等,都是网络的资源.在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就会变坏.这种情况就叫做拥塞. 拥塞控制就 ...

  3. iOS_数据存取(二)

    本节内容目录: 一.SQLite3 二.Core Data 一.SQlite3 SQLite3是⼀款开源的嵌入式关系型数据库,可移植性好.易使用.内存开销小SQLite3是⽆类型的,意味着你可以保存任 ...

  4. Git使用http clone客户端保存用户名密码

    使用Git Bash时,用命令git pull或git push时总是要输入密码,很烦躁 解决办法 需要注意的是,这个方法是在Windows下使用 1. 新建环境变量   HOME 值为 %USERP ...

  5. 【P2964】硬币的游戏(DP+前缀和)

    一道DP,思维难度真是不小. 首先对于这个题的数据,我们可以发现差不多可以支持n^2logn,但是貌似也不会有这种复杂度的线性DP(至少这个题看上去不是这样).所以我们考虑N^2做法.因为求得是价值和 ...

  6. spring boot 使用thymeleaf3.0以及thymeleaf的热部署

    spring boot 截止1.5.4,默认使用thymeleaf2.0,会有一些很蛋疼的地方比如xml格式之类的,具体哪些就不说了 -> 替换为3.0版本 pom中加入 <propert ...

  7. js多个<ul>相应不同的点击事件

    $('ul').on("click","li#left",function(){ currentProvince = $(this).text().replac ...

  8. Mine_目标

    1. hibernate 有简单的方式 可以用于 DDL操作吗? “ DDL(data definition language)是数据定义语言:DDL比DML要多,主要的命令有CREATE.ALTER ...

  9. SSIS之序列容器

    序列容器是一种十分简单,但使用非常广泛的容器,它可以对控制流的任务流组件进行结构化处理,把一些业务相关的任务组件,放到一个序列容器中,使整个包看起来更加整洁.美观,就如同我们家里的书柜.衣柜似的,把不 ...

  10. Splash设置

    平常这个东西是自动充满屏幕的,今天一下子居中只显示1/4了.原来不小心改动了这里 splash scaling属性,改回这个就没问题了