HYSBZ - 2243 染色 (树链剖分+线段树)
题意:树上每个结点有自己的颜色,支持两种操作:1.将u到v路径上的点颜色修改为c; 2.求u到v路径上有多少段不同的颜色。
分析:树剖之后用线段树维护区间颜色段数。区间查询区间修改。线段树结点中维护的有:段数,左端点颜色,右端点颜色和懒惰标记。
当区间合并时,若左孩子的右端点颜色和右孩子的左端点颜色相同,那么段数要减1。
区间修改时注意维护左右端点的颜色。
查询时若左右子区间连接处的颜色相同,段数减1。
在两点向一条链上寻找LCA时,每次查询都要保存该条链顶端的颜色,若该链顶端的颜色与下次查询的右端点相同,那么段数减1。
最后当两点回溯到一条链上之后,若两点对应各自上次回溯链顶端的颜色是否与查询区间的左右端点相同,则答案都需减1。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define lson rt<<1
#define rson rt<<1|1
#define Lson l,m,lson
#define Rson m+1,r,rson
typedef long long LL;
using namespace std;
const int maxn =1e5+;
struct Edge{
int to,next;
}E[*maxn];
int n,head[maxn],tot;
int cnt,idx,size[maxn],fa[maxn],son[maxn],dep[maxn],top[maxn],id[maxn],rnk[maxn];
int a[maxn];
void init()
{
cnt=idx=tot=;
memset(head,-,sizeof(head));
dep[]=,fa[]=,size[]=;
memset(son,,sizeof(son));
} void AddEdge(int u,int v)
{
E[tot] = (Edge){v,head[u]};
head[u]=tot++;
}
void dfs1(int u)
{
size[u]=;
for(int i=head[u];~i;i=E[i].next){
int v=E[i].to;
if(v!=fa[u]){
fa[v]=u;
dep[v]=dep[u]+;
dfs1(v);
size[u]+=size[v];
if(size[son[u]]<size[v]) son[u]=v;
}
}
} void dfs2(int u,int topu)
{
top[u]= topu;
id[u] = ++idx;
rnk[idx] = u;
if(!son[u]) return;
dfs2(son[u],top[u]);
for(int i=head[u];~i;i=E[i].next){
int v=E[i].to;
if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
} struct Node{
int sum,add,lc,rc;
}tree[maxn<<];
int Lc,Rc;
void pushup(int rt){ //区间合并
tree[rt].sum = tree[lson].sum + tree[rson].sum;
tree[rt].lc = tree[lson].lc;
tree[rt].rc = tree[rson].rc;
if(tree[lson].rc==tree[rson].lc)
tree[rt].sum--;
}
void pushdown(int l,int r,int rt){
if(tree[rt].add){
tree[lson].add = tree[rson].add = ;
tree[lson].sum = tree[rson].sum = ;
tree[lson].lc = tree[lson].rc = tree[rt].lc;
tree[rson].lc = tree[rson].rc = tree[rt].lc;
tree[rt].add = ;
}
} void build(int l,int r,int rt)
{
tree[rt].add = ;
if(l==r){
tree[rt].sum = ;
tree[rt].lc = tree[rt].rc = a[rnk[l]];
return;
}
int m = (l+r)>>;
build(Lson);
build(Rson);
pushup(rt);
} void update(int L,int R,int col,int l=,int r=n,int rt=){
if(L<=l && R>=r){
tree[rt].sum = tree[rt].add =;
tree[rt].lc = tree[rt].rc = col;
return ;
}
pushdown(l,r,rt);
int m =(l+r)>>;
if(L<=m) update(L,R,col,Lson);
if(R>m) update(L,R,col,Rson);
pushup(rt);
} int query(int L,int R,int l=,int r=n,int rt=){ //单点
if(L==l) Lc = tree[rt].lc;
if(R==r) Rc = tree[rt].rc;
if(L<=l && R>=r)
return tree[rt].sum;
pushdown(l,r,rt);
int m = (l+r)>> , ans=; bool left = false;
if(L<=m) {
ans+=query(L,R,Lson);
left = true;
}
if(R>m){
ans +=query(L,R,Rson);
if(left && tree[lson].rc ==tree[rson].lc) ans--;
}
pushup(rt);
return ans;
} void CHANGE(int u,int v,int col)
{
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
update(id[top[u]],id[u],col);
u = fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
update(id[u],id[v],col);
} int Qsum(int u,int v)
{
int c1=-,c2=-, ans=; //记录上条链最左侧的颜色
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]){
swap(u,v);
swap(c1,c2);
}
ans +=query(id[top[u]],id[u]);
if(Rc == c1) ans--;
c1 = Lc;
u = fa[top[u]];
}
if(dep[u]>dep[v]){swap(u,v);swap(c1,c2);}
ans += query(id[u],id[v]);
if(Lc==c1) ans--;
if(Rc==c2) ans--;
return ans;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int m,q,u,v;
char op[];
while(scanf("%d%d",&n,&m)==){
init();
for(int i=;i<=n;++i) scanf("%d",&a[i]);
for(int i=;i<n;++i){
scanf("%d%d",&u,&v);
AddEdge(u,v);
AddEdge(v,u);
}
dfs1();
dfs2(,);
build(,n,);
while(m--){
scanf("%s",op);
if(op[]=='Q'){
scanf("%d%d",&u,&v);
printf("%d\n",Qsum(u,v));
}
else{
int col;
scanf("%d%d%d",&u,&v,&col);
CHANGE(u,v,col);
}
}
}
return ;
}
HYSBZ - 2243 染色 (树链剖分+线段树)的更多相关文章
- 2243: [SDOI2011]染色 树链剖分+线段树染色
给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- B20J_2243_[SDOI2011]染色_树链剖分+线段树
B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...
- BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)
题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- 【bzoj1959】[Ahoi2005]LANE 航线规划 树链剖分+线段树
题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
随机推荐
- js控制button
按钮变灰不可用方法:document.getElementById("crop").setAttribute("disabled", true); 按钮可用方法 ...
- ubuntu 14.04 中安装R和Rstudio
1. 安装R 1.1 首先添加镜像源 sudo gedit /etc/apt/sources.list # 加入新镜像源: deb http://cran.rstudio.com/bin/linux/ ...
- oralce 术语
§2.1 术语 l 数据库块(BLOCK) ORACLE 数据库中的最小存储和处理单位,包含块本身的头信息数据或PL/SQL代码. ORACLE 块的大小是可以在安装时选择“自定义安装”来指定,也可以 ...
- Android无线测试之—UiAutomator UiCollection API介绍
UiCollection类介绍 一.UiCollection类说明 1)UiCollection类是UiObject类的子类,即UiObject类的所有方法都被UiCollection继承下来了,都可 ...
- 如何结合IbatisNet的LIST遍历实现模糊查询
我仿照Java的Spring+Ibatis+Struct用Castle+IBatisNet+Asp.net的开发框架的DAO的基类:BaseSqlMapDao内定义了一个内部类来辅助模糊查询.内部类代 ...
- 【BZOJ3875】[Ahoi2014&Jsoi2014]骑士游戏 SPFA优化DP
[BZOJ3875][Ahoi2014&Jsoi2014]骑士游戏 Description [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会扮演一个英勇的 ...
- CodeForces 156A Message(暴力)
A. Message time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...
- 学习使用turtlebot2——ROS上安装turtlebot2
安装环境: 安装Ubuntu 14.04版本和ROS Indigo 参考:http://wiki.ros.org/turtlebot/Tutorials 安装步骤 有两种安装方法,一种直接的安 ...
- 《挑战程序设计竞赛》2.5 最短路 AOJ0189 2249 2200 POJ3255 2139 3259 3268(5)
AOJ0189 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0189 题意 求某一办公室到其他办公室的最短距离. 多组输入,n表示 ...
- 如何看懂ORACLE执行计划
如何看懂Oracle执行计划 一.什么是执行计划 An explain plan is a representation of the access path that is taken when a ...