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

一下午净调这题了,争取晚上多做几道。

题意:

给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),
如“112221”由3段组成:“11”、“222”和“1”。
 
分析:
线段树结点维护信息:区间内颜色段数t ,区间左端点颜色lco,区间右端点颜色rco,延迟标记lazy。
上传时lco[pos]=lco[lson];rco[pos]=rco[rson];t[pos]=t[lson]+t[rson];如果左区间右端点和右区间左端点颜色相同,区间段数减一;
查询时先加上区间对应的颜色段数(线段树区间合并),然后每次找到上下端点的颜色(直接单点查找),这个跳链的时候就能找到,如果UC=DC,ans--;
注意每次标记下传的时机。
 
代码
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 1000010
#define M 2062145
#define lson pos<<1
#define rson pos<<1|1
int head[N],to[N<<1],nxt[N<<1],co[N],cnt,n,m,scc;
char ch[10];
int dep[N],fa[N],siz[N],son[N],top[N];
int t[M],lzy[M],idx[N],lco[M],rco[M],a[N];
inline void read(int &x)
{
int f=1;x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
x*=f;
}
inline void add(int u,int v)
{
to[++cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt;
}
inline void dfs1(int x,int y)
{
dep[x]=dep[y]+1;
fa[x]=y;
siz[x]=1;
for(int i=head[x];i;i=nxt[i])
{
if(to[i]!=y)
{
dfs1(to[i],x);
siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[son[x]])
{
son[x]=to[i];
}
}
}
}
inline void dfs2(int x,int t)
{
top[x]=t;
idx[x]=++scc;
if(son[x])dfs2(son[x],t);
for(int i=head[x];i;i=nxt[i])
{
if(to[i]!=fa[x]&&to[i]!=son[x])
{
dfs2(to[i],to[i]);
}
}
}
inline void pud(int pos)
{
if(!lzy[pos])return ;
t[lson]=1;lzy[lson]=lco[lson]=rco[lson]=lzy[pos];
t[rson]=1;lzy[rson]=lco[rson]=rco[rson]=lzy[pos];
lzy[pos]=0;
}
inline void up(int l,int r,int pos,int x,int y,int c)
{
if(x<=l&&y>=r)
{
t[pos]=1;
lco[pos]=c;
rco[pos]=c;
lzy[pos]=c;
return ;
}
pud(pos);
int mid=l+r>>1;
if(x<=mid)up(l,mid,lson,x,y,c);
if(y>mid)up(mid+1,r,rson,x,y,c);
t[pos]=t[lson]+t[rson];
if(lco[rson]==rco[lson])t[pos]--;
lco[pos]=lco[lson];
rco[pos]=rco[rson];
}
inline int query(int l,int r,int pos,int x,int y)
{
pud(pos);
int re=0;
int mid=l+r>>1;
if(x<=l&&y>=r)
{
return t[pos];
}
if(y<=mid) return query(l,mid,lson,x,y);
else if(x>mid) return query(mid+1,r,rson,x,y);
else
{
re=query(l,mid,lson,x,y)+query(mid+1,r,rson,x,y);
if(lco[rson]==rco[lson])re--;
return re;
}
}
inline int col(int l,int r,int x,int pos)
{
pud(pos);
if(l==r)return lco[pos];
int mid=l+r>>1;
if(x<=mid)return col(l,mid,x,lson);
else return col(mid+1,r,x,rson);
}
int main()
{
read(n),read(m);
int x,y,z;
register int i;
for(i=1;i<=n;++i)
{
read(a[i]);
}
for(i=1;i<n;++i)
{
read(x),read(y);
add(x,y);
add(y,x);
}
dfs1(1,0);
dfs2(1,1);
for(i=1;i<=n;++i)up(1,n,1,idx[i],idx[i],a[i]);
while(m--)
{
scanf("%s",ch);
if(ch[0]=='C')
{
read(x),read(y),read(z);
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]])swap(x,y);
up(1,n,1,idx[top[y]],idx[y],z);
y=fa[top[y]];
}
if(dep[x]<dep[y])swap(x,y);
up(1,n,1,idx[y],idx[x],z);
}
else
{
read(x),read(y);
int ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]])swap(x,y);
int DC=col(1,n,idx[top[y]],1),UC=col(1,n,idx[fa[top[y]]],1);
ans+=query(1,n,1,idx[top[y]],idx[y]);
if(UC==DC)ans--;
y=fa[top[y]];
}
if(dep[x]<dep[y])swap(x,y);
ans+=query(1,n,1,idx[y],idx[x]);
if(!ans)ans=1;
printf("%d\n",ans);
}
}
}

B20J_2243_[SDOI2011]染色_树链剖分+线段树的更多相关文章

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

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

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

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

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

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

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

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

  5. B20J_2836_魔法树_树链剖分+线段树

    B20J_2836_魔法树_树链剖分+线段树 题意: 果树共有N个节点,其中节点0是根节点,每个节点u的父亲记为fa[u].初始时,这个果树的每个节点上都没有果子(即0个果子). Add u v d ...

  6. B20J_3231_[SDOI2014]旅行_树链剖分+线段树

    B20J_3231_[SDOI2014]旅行_树链剖分+线段树 题意: S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教. S国 ...

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

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  8. 【bzoj1959】[Ahoi2005]LANE 航线规划 树链剖分+线段树

    题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...

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

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

随机推荐

  1. sqlite db数据的导出

    sqlite的db数据一般是filename.db的格式,用普通文本编辑器打开是乱码,用sqlite名令操作比较麻烦,有时版本格式问题还会起阻扰,有一个GUI工具可以对sqlite db格式数据进行管 ...

  2. Java面试题全集(上-中-下)及Java面试题集(1-50/51-70)

    阅读量超百万级的文章,收藏并分享一下.感谢原创作者的总结 对初中级java开发人员有特别大的帮助,不论是技术点面试还是知识点总结上. Java面试题全集(上):     https://blog.cs ...

  3. JSF-使用JSF标记

    使用JSF标记 基于Facelets技术的JSF页面是一个 XHTML页面,文件扩展名为 .xhtml 1)JSF页面可用html标记,但必须满足: ①所有标记都必须闭合.如<p>开始,& ...

  4. C语言出来多久了你知道吗?

    在20世纪80年代,为了避免不同开发者使用的C语言语法的差异,美国国家标准局为C语言开发了一套完整的美国国家标准语言文法,称为ANSI C,作为C语言的初始标准.. [1] 2011年12月8日,国际 ...

  5. 浏览器渲染原理笔记 --《How Browser Work》读后总结

    综述 之前使用ExtJS时遇到一个问题:为什么依次设置多个组件的可见性界面会卡顿?在了解HTML的dom操作相关内容的时候也好奇这个东西到底是怎么回事,然后尤其搞不懂CSS和Html分管样式和网页结构 ...

  6. JQuery(三)-- AJAX的深入理解以及JQuery的使用

    HTTP HTTP http: 超文本传输协议.特点:  简单.快速.灵活.无状态.无连接 URL: 统一资源定位符. 组成:协议名://主机IP:端口号/项目资源地址?传递参数的键值对#锚点 ①ip ...

  7. 解决150%DPI下Photoshop不能显示成合适大小的问题

    Adobe官方这里一直不给力,只能靠自己动手了. 和解决CHM高分屏显示的步骤差不多: Ctril+R,输入regedit编辑注册表. 进入到 HKEY_LOCAL_MACHINE > SOFT ...

  8. 【转】简单了介绍js中的一些概念(词法结构) 和 数据类型(部分)。

    1 , javascript字符集: javascript采用的是Unicode字符集编码. 为什么要采用这个编码呢? 原因很简单,16位的Unicode编码可以表示地球人的任何书面语言.这是语言 国 ...

  9. Data_r_and_w(csv,json,xlsx)

    import osimport sysimport argparsetry:    import cStringIO as StringIOexcept:    import StringIOimpo ...

  10. JAVA学习资源分享

    JAVA学习资源分享 最高端的JAVA架构师资源(来自龙果学院 价值¥1399元).JAVA互联网分布式架构(龙果学院 价值¥899元).Spring Boot(2017年最新 包括源码原理分析) + ...