[SDOI2011]染色

题目描述

给定一棵有n个节点的无根树和m个操作,操作有2类:

1、将节点a到节点b路径上所有点都染成颜色c;

2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),

如“112221”由3段组成:“11”、“222”和“1”。

请你写一个程序依次完成这m个操作。

输入输出格式

输入格式

第一行包含2个整数n和m,分别表示节点数和操作数;

第二行包含n个正整数表示n个节点的初始颜色

下面 行每行包含两个整数x和y,表示x和y之间有一条无向边。

下面 行每行描述一个操作:

“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;

“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。

输出格式

对于每个询问操作,输出一行答案。

说明

数N<=105,操作数M<=105,所有的颜色C为整数且在[0, 10^9]之间。


本来想复习一下树剖的,谁知道这题打起来超恶心。。

线段树上维护一下区间左端点颜色和右端点颜色,多的减掉就行啦


Code:

#include <cstdio>
#define ls id<<1
#define rs id<<1|1
int min(int x,int y){return x<y?x:y;}
int max(int x,int y){return x>y?x:y;}
const int N=2e5+10;
int head[N],to[N],Next[N],cnt;
void add(int u,int v)
{
to[++cnt]=v;Next[cnt]=head[u];head[u]=cnt;
}
int top[N],dep[N],siz[N],f[N],dfn[N],ws[N],ha[N],dfs_clock,n,m;
void dfs1(int now)
{
++siz[now];
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(f[now]!=v)
{
dep[v]=dep[now]+1;
f[v]=now;
dfs1(v);
siz[now]+=siz[v];
if(siz[ws[now]]<siz[v])
ws[now]=v;
}
}
}
void dfs2(int now,int anc)
{
dfn[now]=++dfs_clock;
ha[dfs_clock]=now;
top[now]=anc;
if(ws[now]) dfs2(ws[now],anc);
for(int i=head[now];i;i=Next[i])
if(!dfn[to[i]])
dfs2(to[i],to[i]);
}
int clo[N],lc[N<<2],rc[N<<2],sum[N<<2],lazy[N<<2];
void updata(int id)//保证不为叶子
{
sum[id]=sum[ls]+sum[rs]-(rc[ls]==lc[rs]);
lc[id]=lc[ls];
rc[id]=rc[rs];
}
void build(int id,int l,int r)
{
if(l==r)
{
lc[id]=rc[id]=clo[ha[l]];
sum[id]=1;
return;
}
int mid=l+r>>1;
build(ls,l,mid);
build(rs,mid+1,r);
updata(id);
}
void pushdown(int id)//保证不为叶子
{
if(lazy[id])
{
lazy[ls]=lazy[rs]=lc[ls]=lc[rs]=rc[ls]=rc[rs]=lazy[id];
sum[ls]=sum[rs]=1;
lazy[id]=0;
}
}
int line=0;
void change(int id,int l,int r,int L,int R,int color)
{
if(L!=R) pushdown(id);
if(l==L&&r==R)
{
lazy[id]=lc[id]=rc[id]=color;
sum[id]=1;
return;
}
int Mid=L+R>>1;
if(r<=Mid) change(ls,l,r,L,Mid,color);
else if(l>Mid) change(rs,l,r,Mid+1,R,color);
else change(ls,l,Mid,L,Mid,color),change(rs,Mid+1,r,Mid+1,R,color);
updata(id);
}
int query(int id,int l,int r,int L,int R,int &cl,int &cr)
{
if(L!=R) pushdown(id);
if(l==L&&r==R)
{
cl=lc[id],cr=rc[id];
return sum[id];
}
int Mid=L+R>>1,c0,c1;
if(r<=Mid) return query(ls,l,r,L,Mid,cl,cr);
else if(l>Mid) return query(rs,l,r,Mid+1,R,cl,cr);
else return query(ls,l,Mid,L,Mid,cl,c0)+query(rs,Mid+1,r,Mid+1,R,c1,cr)-(rc[ls]==lc[rs]);
}
void t_change(int x,int y,int c)
{
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]])
{
change(1,dfn[top[x]],dfn[x],1,n,c);
x=f[top[x]];
}
else
{
change(1,dfn[top[y]],dfn[y],1,n,c);
y=f[top[y]];
}
}
change(1,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),1,n,c);
}
int t_query(int x,int y)
{
int s=0,xc=0,yc=0,cl,cr;
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]])
{
s+=query(1,dfn[top[x]],dfn[x],1,n,cl,cr);
s-=cr==xc;
xc=cl;
x=f[top[x]];
}
else
{
s+=query(1,dfn[top[y]],dfn[y],1,n,cl,cr);
s-=cr==yc;
yc=cl;
y=f[top[y]];
}
}
s+=query(1,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),1,n,cl,cr);
if(dfn[x]<dfn[y]) s-=(cl==xc)+(cr==yc);
else s-=(cl==yc)+(cr==xc);
return s;
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",clo+i);
for(int u,v,i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
dfs1(1),dfs2(1,1);
build(1,1,n);
char op[21];
for(int a,b,c,i=1;i<=m;i++)
{
scanf("%s%d%d",op,&a,&b);
if(op[0]=='C') scanf("%d",&c),t_change(a,b,c);
else printf("%d\n",t_query(a,b));
}
return 0;
}

2018.8.27

洛谷 P2486 [SDOI2011]染色/bzoj 2243: [SDOI2011]染色 解题报告的更多相关文章

  1. 洛谷 P1291 [SHOI2002]百事世界杯之旅 解题报告

    P1291 [SHOI2002]百事世界杯之旅 题目描述 "--在2002年6月之前购买的百事任何饮料的瓶盖上都会有一个百事球星的名字.只要凑齐所有百事球星的名字,就可参加百事世界杯之旅的抽 ...

  2. 洛谷 P4714 「数学」约数个数和 解题报告

    P4714 「数学」约数个数和 题意(假):每个数向自己的约数连边,给出\(n,k(\le 10^{18})\),询问\(n\)的约数形成的图中以\(n\)为起点长为\(k\)的链有多少条(注意每个点 ...

  3. 洛谷 P4345 [SHOI2015]超能粒子炮·改 解题报告

    P4345 [SHOI2015]超能粒子炮·改 题意 求\(\sum_{i=0}^k\binom{n}{i}\),\(T\)组数据 范围 \(T\le 10^5,n,j\le 10^{18}\) 设\ ...

  4. 洛谷 P1691 有重复元素的排列问题 解题报告

    P1691 有重复元素的排列问题 题目描述 设\(R={r_1,r_2,--,r_n}\)是要进行排列的\(n\)个元素.其中元素\(r_1,r_2,--,r_n\)可能相同.使设计一个算法,列出\( ...

  5. 洛谷 P2746 [USACO5.3]校园网Network of Schools 解题报告

    P2746 [USACO5.3]校园网Network of Schools 题目描述 一些学校连入一个电脑网络.那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作"接受学校&q ...

  6. 洛谷 P1121 环状最大两段子段和 解题报告

    P1121 环状最大两段子段和 题目描述 给出一段环状序列,即认为\(A_1\)和\(A_N\)是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 第一行是一个正整数 ...

  7. 洛谷 P1120 小木棍 [数据加强版]解题报告

    P1120 小木棍 [数据加强版] 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它 ...

  8. 洛谷 P2336 [SCOI2012]喵星球上的点名 解题报告

    P2336 [SCOI2012]喵星球上的点名 题目描述 a180285 幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有 \(N\) 个喵星人,每个喵星人的 ...

  9. 洛谷 P2862 [USACO06JAN]把牛Corral the Cows 解题报告

    P2862 [USACO06JAN]把牛Corral the Cows 题目描述 Farmer John wishes to build a corral for his cows. Being fi ...

随机推荐

  1. JZOJ 5934. 列队

    Description         Sylvia是一个热爱学习的女孩子.        在平时的练习中,他总是能考到std以上的成绩,前段时间,他参加了一场练习赛,众所周知,机房是一个 的方阵.这 ...

  2. ajax提交时 富文本CKEDITOR 获取不到内容

    ckeditor数据向content(页面用以替换的编辑框)的同步 问题: 我们发现,在数据通过ajaxSubmit提交的过程中,并不能将最新的数据进行提交.换句话说,最新的数据无法被jQuery.f ...

  3. Hue联合(hdfs yarn hive) 后续......................

    1.启动hdfs,yarn start-all.sh 2.启动hive $ bin/hive $ bin/hive --service metastore & $ bin/hive --ser ...

  4. tomcat+nginx+keepalived的配置

    tomcat+nginx+keepalived的配置 1.在官网上下载Tomcat 2.将压缩包解压,并且移动到/opt/data/的目录下. .tar.gz /opt/data/ 3.进入到Tomc ...

  5. 前端学习之HTML基础

    要点: 理解HTTP请求响应模式及通信规范 HTML的各种标签和常用标签 CSS是用于样式渲染和定位布局 JS将HTML动态化 jquery是JS的高级封装 理解HTTP请求响应模式及通信规范 HTT ...

  6. PHP json_decode返回null解析失败原因

    在PHP5.4之前 json_decode函数有两个参数json_decode有两个参数,第一个是待解析的字符串,第二个是是否解析为Array json_decode要求的字符串比较严格:(1)使用U ...

  7. MFC接收ShellExecute多个参数

    在应用程序开发过程中,我们经常需要带参数启动另一个执行程序,如何传递多个参数,如何解析多个参数呢?   传参数 传递参数可使用ShellExecute函数,示例如下: ShellExecute(NUL ...

  8. 1.使用pycharm搭建开发调试环境【转】

    感谢 feigamesnb 第一步:安装python2.7环境 去https://www.python.org/downloads/下载windows版本的python,选择2.7版本,按提示安装,并 ...

  9. 【数据结构】 Queue 的简单实现

    [数据结构] Queue 的简单实现 public class XQueue<T> { /// <summary> /// 第一个元素 /// </summary> ...

  10. inline-block 空隙

    IE8-9.Firefox.Safari 是4px Chrome下是8px 出现原因 标签换行引起 解决方案网上很多 但是在布局中尽量避免使用inline-block