Problem 染色(BZOJ2243)

题目大意

  给定一颗树,每个节点上有一种颜色。

  要求支持两种操作:

    操作1:将a->b上所有点染成一种颜色。

    操作2:询问a->b上的颜色段数量。

解题分析

  树链剖分+线段树。

  开一个记录类型,记录某一段区间的信息。l 表示区间最左侧的颜色 , r 表示区间最右侧的颜色 , sum 表示区间中颜色段数量。

  合并时判断一下左区间的右端点和有区间的左端点的颜色是否一样。

  树上合并时需要用两个变量ans1,ans2来存储。ans1表示x往上走时形成的链的信息,ans2表示y往上走时形成链的信息。

  当x和y位于同一条重链上时,有三个区间需要合并在一起,注意判断顺序。

参考程序

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; #define V 100008
#define E 200008
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 int n,m,cnt;
int a[V],size[V],dep[V],fa[V],son[V],top[V],w[V],rk[V]; struct line{
int u,v,nt;
}eg[E];
int sum,lt[V]; struct color{
int l,r,sum;
color(int a=-,int b=-,int c=-):l(a),r(b),sum(c){}
};
color merge(color a,color b){
color c;
if (a.sum==-) return b;
if (b.sum==-) return a;
if (a.r==b.l){
c.sum=a.sum+b.sum-;
c.l=a.l;
c.r=b.r;
}
else
{
c.sum=a.sum+b.sum;
c.l=a.l;
c.r=b.r;
}
return c;
} struct segment_tree{
color tag[V<<];
int lazy[V<<];
void pushup(int rt){
tag[rt]=merge(tag[rt<<],tag[rt<<|]);
}
void pushdown(int rt){
if (lazy[rt]){
lazy[rt<<]=lazy[rt<<|]=lazy[rt];
tag[rt<<].l=tag[rt<<].r=lazy[rt];
tag[rt<<|].l=tag[rt<<|].r=lazy[rt];
tag[rt<<].sum=tag[rt<<|].sum=;
lazy[rt]=;
return;
}
}
void build(int l,int r,int rt){
if (l==r){
tag[rt].l=tag[rt].r=a[rk[l]];
tag[rt].sum=;
return;
}
int m=(l+r)/;
build(lson);
build(rson);
pushup(rt);
}
void update(int L,int R,int val,int l,int r,int rt){
if (L<=l && r<=R){
tag[rt].l=tag[rt].r=val;
tag[rt].sum=;
lazy[rt]=val;
return;
}
pushdown(rt);
int m=(l+r)/;
if (L <= m) update(L,R,val,lson);
if (m < R) update(L,R,val,rson);
pushup(rt);
}
color query(int L,int R,int l,int r,int rt){
if (L<=l && r<=R){
return tag[rt];
}
pushdown(rt);
color res;
int m=(l+r)/;
if (L <= m) res=merge(res,query(L,R,lson));
if (m < R) res=merge(res,query(L,R,rson));
return res;
}
}T; void adt(int u,int v){
eg[++sum].u=u; eg[sum].v=v; eg[sum].nt=lt[u]; lt[u]=sum;
}
void add(int u,int v){
adt(u,v); adt(v,u);
} void dfs_1(int u){
size[u]=; dep[u]=dep[fa[u]]+; son[u]=;
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (v==fa[u]) continue;
fa[v]=u;
dfs_1(v);
size[u]+=size[v];
if (size[v]>size[son[u]]) son[u]=v;
}
}
void dfs_2(int u,int tp){
w[u]=++cnt; top[u]=tp; rk[cnt]=u;
if (son[u]) dfs_2(son[u],tp);
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (v==fa[u] || v==son[u]) continue;
dfs_2(v,v);
}
}
void change(int x,int y,int val){
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) swap(x,y);
T.update(w[top[x]],w[x],val,,n,);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
T.update(w[x],w[y],val,,n,);
}
void pt(color a){
printf("%d %d %d\n",a.l,a.r,a.sum);
}
void find(int x,int y){
color ans1,ans2,ans;
while (top[x]!=top[y]){
if (dep[top[x]]>dep[top[y]]){
ans1=merge(T.query(w[top[x]],w[x],,n,),ans1);
x=fa[top[x]];
}
else
{
ans2=merge(T.query(w[top[y]],w[y],,n,),ans2);
y=fa[top[y]];
} }
if (dep[x]<dep[y]){
ans=T.query(w[x],w[y],,n,);
ans=merge(ans,ans2);
swap(ans.l,ans.r);
ans=merge(ans,ans1);
}
else
{
ans=T.query(w[y],w[x],,n,);
ans=merge(ans,ans1);
swap(ans.l,ans.r);
ans=merge(ans,ans2);
}
printf("%d\n",ans.sum );
} int main(){
memset(lt,,sizeof(lt)); sum=; cnt=;
scanf("%d %d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i]);
for (int i=;i<n;i++){
int u,v;
scanf("%d %d",&u,&v);
add(u,v);
}
dfs_1();
dfs_2(,);
T.build(,n,);
while (m--){
char ch[];
int x,y,z;
scanf("%s",ch);
if (ch[]=='Q'){
scanf("%d %d",&x,&y);
find(x,y);
}
else
{
scanf("%d %d %d",&x,&y,&z);
change(x,y,z);
};
}
}

BZOJ2243 (树链剖分+线段树)的更多相关文章

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

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

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

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

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

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

  4. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  5. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  6. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  7. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  8. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  9. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

随机推荐

  1. IE5,IE6,IE7,IE8的css兼容性列表[转自MSDN]

    CSS 2.1:   IE 5.0 IE 5.5 IE 6.0 IE 7.0 IE8 Beta 1 IE8 Beta 2 IE 8.0 @charset No Yes Yes Yes Yes Yes ...

  2. Java集合——Set接口

    1.定义 set中不允许放入重复的元素(元素相同时只取一个),使用equals()方法进行比较.如果返回true,两个对象的HashCode值也应该相等 2.方法 add():添加元素 remove( ...

  3. iscroll4框架解析[webapp开发](转)

    概要 iScroll 4 这个版本完全重写了iScroll这个框架的原始代码.这个项目的产生完全是因为移动版webkit浏览器(诸如iPhone,iPad,Android 这些系统上广泛使用)提供了一 ...

  4. easyui中的combobox小知识点~~

    一直使用的easyui中,一些不为人知的小知识点,与君共勉: 1.combobox设置高度:使用panelHeight属性: 2.combobox本身自带“自动补全”功能,但是在浏览器中是有限制的,在 ...

  5. Excel VBA记录

    -----------快捷键---------- 函数等提示(默认):ctrl+j 注释:上单引号' 设置单元格为空可以用:empty/null -----------基础语法--------- 基本 ...

  6. 所思所想 关于asp.net界面业务分离

    1.体会:使用ASP.NET控件来做前段是有很大的局限性的 2.使用拼接HTML的方式来写代码虽然不符合模式,但是有很大的灵活性 3.如果使用拼接字符串的方式来生成前台的代码,使用NV的话完全可以实现 ...

  7. 一个socket发送调试信息的类

    using UnityEngine; using System.Collections; using System; using System.Net.Sockets; using System.Ne ...

  8. HDU 3085 Nightmare II 双向bfs 难度:2

    http://acm.hdu.edu.cn/showproblem.php?pid=3085 出的很好的双向bfs,卡时间,普通的bfs会超时 题意方面: 1. 可停留 2. ghost无视墙壁 3. ...

  9. Linux中如何让命令在后台运行

    1.在下达的命令后面加上&,就可以使该命令在后台进行工作,这样做最大的好处就是不怕被ctrl+c这个中断指令所中断. 2. 那大家可能又要问了,在后台执行的程序怎么使它恢复到前台来运行呢?很简 ...

  10. zoj2132-The Most Frequent Number

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2132 The Most Frequent Number Time Limi ...