[bzoj2243][SDOI2011]染色
Description
给定一棵有$n$个节点的无根树和$m$个操作,操作有$2$类:
1.将节点$a$到节点$b$路径上所有点都染成颜色$c$;
2.询问节点$a$到节点$b$路径上的颜色段数量(连续相同颜色被认为是同一段),如$"112221"$由$3$段组成:$"11","222"和"1"$.
请你写一个程序依次完成这$m$个操作.
Input
第一行包含$2$个整数$n$和$m$,分别表示节点数和操作数.
第二行包含$n$个正整数表示$n$个节点的初始颜色.
下面$n-1$行每行包含两个整数$x$和$y$,表示$x$和$y$之间有一条无向边.
下面$m$行每行描述一个操作:
$”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,M\;\leq\;10^5,c\;\in\;z,c\;\in\;[0, 10^9]$.
Solution
树链剖分+线段树.
每次上移的时候判断相邻两段端点是否同色即可.
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 100005
#define M 300005
using namespace std;
struct linetree{
int l,r,lc,rc,cnt;
}lt[M];
struct graph{
int nxt,to;
}e[M];
char c[2];
int g[N],a[N],w[N],n,m,u,v,k,l,cnt;
int f[N],p[N],dep[N],siz[N],son[N],top[N];
inline void addedge(int x,int y){
e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y;
}
inline void dfs1(int u){
int m=0;siz[u]=1;
for(int i=g[u];i;i=e[i].nxt)
if(!dep[e[i].to]){
f[e[i].to]=u;
dep[e[i].to]=dep[u]+1;
dfs1(e[i].to);
siz[u]+=siz[e[i].to];
if(siz[e[i].to]>m){
son[u]=e[i].to;
m=siz[e[i].to];
}
}
}
inline void dfs2(int u,int tp){
top[u]=tp;p[u]=++cnt;w[cnt]=a[u];
if(son[u]) dfs2(son[u],tp);
for(int i=g[u];i;i=e[i].nxt)
if(f[u]!=e[i].to&&e[i].to!=son[u])
dfs2(e[i].to,e[i].to);
}
inline void build(int u,int l,int r){
lt[u].l=l;lt[u].r=r;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
build(lef,l,mid);build(rig,mid+1,r);
lt[u].cnt=lt[lef].cnt+lt[rig].cnt;
if(lt[lef].rc==lt[rig].lc) --lt[u].cnt;
lt[u].lc=lt[lef].lc;lt[u].rc=lt[rig].rc;
}
else{
lt[u].cnt=1;lt[u].lc=lt[u].rc=w[lt[u].l];
}
}
inline void cover(int u,int l,int r,int k){
if(lt[u].l>=l&<[u].r<=r){
lt[u].lc=lt[u].rc=k;lt[u].cnt=1;
}
else if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
if(lt[u].cnt==1){
lt[lef].cnt=lt[rig].cnt=1;
lt[lef].lc=lt[lef].rc=lt[rig].lc=lt[rig].rc=lt[u].lc;
}
if(l<=mid) cover(lef,l,r,k);
if(r>mid) cover(rig,l,r,k);
lt[u].cnt=lt[lef].cnt+lt[rig].cnt;
if(lt[lef].rc==lt[rig].lc) --lt[u].cnt;
lt[u].lc=lt[lef].lc;lt[u].rc=lt[rig].rc;
}
}
inline int ask(int u,int l,int r){
if(lt[u].l>=l&<[u].r<=r)
return lt[u].cnt;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1,ret=0;
int mid=(lt[u].l+lt[u].r)>>1;
if(lt[u].cnt==1){
lt[lef].cnt=lt[rig].cnt=1;
lt[lef].lc=lt[rig].lc=lt[lef].rc=lt[rig].rc=lt[u].lc;
}
if(l<=mid) ret+=ask(lef,l,r);
if(r>mid) ret+=ask(rig,l,r);
if(l<=mid&&r>mid&<[lef].rc==lt[rig].lc) --ret;
return ret;
}
}
inline int col(int u,int x){
if(lt[u].l==x) return lt[u].lc;
if(lt[u].r==x) return lt[u].rc;
if(lt[u].l<lt[u].r){
int lef=u<<1,rig=u<<1|1;
int mid=(lt[u].l+lt[u].r)>>1;
if(lt[u].cnt==1){
lt[lef].cnt=lt[rig].cnt=1;
lt[lef].lc=lt[rig].lc=lt[lef].rc=lt[rig].rc=lt[u].lc;
}
if(x<=mid) return col(lef,x);
return col(rig,x);
}
}
inline void cov(int x,int y,int k){
int t;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
t=x;x=y;y=t;
}
cover(1,p[top[x]],p[x],k);
x=f[top[x]];
}
if(p[x]>p[y]){
t=x;x=y;y=t;
}
cover(1,p[x],p[y],k);
}
inline int q(int x,int y){
int ret=0,t;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
t=x;x=y;y=t;
}
ret+=ask(1,p[top[x]],p[x]);
if(col(1,p[top[x]])==col(1,p[f[top[x]]])) --ret;
x=f[top[x]];
}
if(p[x]>p[y]){
t=x;x=y;y=t;
}
ret+=ask(1,p[x],p[y]);
return ret;
}
inline int lca(int x,int y){
int t;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
t=x;x=y;y=t;
}
x=f[top[x]];
}
if(p[x]>p[y]){
t=x;x=y;y=t;
}
return x;
}
inline void Aireen(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1,x,y;i<n;++i){
scanf("%d%d",&x,&y);
addedge(x,y);addedge(y,x);
}
dep[1]=1;dfs1(1);
cnt=0;dfs2(1,1);
build(1,1,n);
while(m--){
scanf("%s%d%d",c,&u,&v);
if(c[0]=='C'){
scanf("%d",&k);cov(u,v,k);
}
else{
l=lca(u,v);
printf("%d\n",q(u,v));
}
}
}
int main(){
freopen("color.in","r",stdin);
freopen("color.out","w",stdout);
Aireen();
fclose(stdin);
fclose(stdout);
return 0;
}
[bzoj2243][SDOI2011]染色的更多相关文章
- BZOJ2243 SDOI2011 染色 【树链剖分】
BZOJ2243 SDOI2011 染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
- BZOJ2243[SDOI2011]染色——树链剖分+线段树
题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221 ...
- [BZOJ2243][SDOI2011]染色 解题报告|树链剖分
Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...
- BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)
题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...
- BZOJ2243: [SDOI2011]染色(树链剖分/LCT)
Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如 ...
- bzoj2243: [SDOI2011]染色--线段树+树链剖分
此题代码量较大..但是打起来很爽 原本不用lca做一直wa不知道为什么.. 后来改lca重打了一遍= =结果一遍就AC了orz 题目比较裸,也挺容易打,主要是因为思路可以比较清晰 另:加读入优化比没加 ...
- BZOJ2243——[SDOI2011]染色
1.题目大意:给个树,然后树上每个点都有颜色,然后会有路径的修改,有个询问,询问一条路径上的颜色分成了几段 2.分析:首先这个修改是树剖可以做的,对吧,但是这个分成了几段怎么搞呢,我们的树剖的不是要建 ...
- bzoj2243 sdoi2011 染色 paint
明明是裸树剖 竟然调了这么久好蛋疼 大概是自己比较水的原因吧 顺便+fastio来gangbang #include<iostream> #include<cstring> # ...
随机推荐
- flask01 安装及初涉
一.安装 1.pip的安装 $ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py $ python get-pip.p ...
- JAZZ
今天知道公司中的JAZZ是变形金刚中的“爵士”,如果写内部代码,就好像在操作“爵士”,还是蛮有意思的.先是接触了jQuery,然后是jQuery-ui,然后jazz,继续中...... JAZZ: 爵 ...
- PHP代码20个实用技巧(转)
这些技巧特别是封装的,相对路径的还是挺好的,本身来自微信公众号,但是我担心以后删除,所以在我的博客上备份一下(微信公众号为:菜鸟教程) 在这篇文章中我们将看看一些关于PHP开发有用的提示和技巧,可以用 ...
- js读取解析JSON类型数据(转)
谢谢博主,转自http://blog.csdn.net/beyond0851/article/details/9285771 一.什么是JSON? JSON(JavaScript Object Not ...
- 洛谷 U4792 Acheing 单调队列
U4792 Acheing 5通过 43提交 题目提供者Acheing 标签 难度尚无评定 提交 最新讨论 暂时没有讨论 题目背景 题目并没有什么含义,只是想宣传一下自己的博客,Acheing.com ...
- NOI2018准备Day19
5天没写. 伸展树 主席树 3到线段树模板题
- c语言中%s与%c对读入字符串的区别
对于scanf函数,需求%s类型时,\n是不会影响scanf内容的对于需求%c类型时,\n也是字符,自然会有影响.
- canvas中的碰撞检测笔记
用 canvas 做小游戏或者特效,碰撞检测是少不了的.本文将会涉及普通的碰撞检测,以及像素级的碰撞检测.(本文的碰撞检测均以矩形为例) 普通碰撞检测 普通的矩形碰撞检测比较简单.即已知两个矩形的各顶 ...
- 基于DDD的.NET开发框架 - ABP领域服务
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- 学堂在线 UWP 首版
好久没有写博客了,主要是最近在写一个小小的App.<( ̄︶ ̄)> 不知道看各位有木有爱看慕课的,作为一名资深的大三学渣的我有看慕课的习惯.一直在看学堂在线的慕课,感觉质量确实还可以,但是遗 ...