[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. apache使用.htaccess文件中RewriteRule重定向后,URL中的加号无法解析

    今天在使用.htaccess做伪静态的时候,发生一件怪事,URL里存在C++时会有问题,在处理C++这个词的时候,无论如何,$_GET都得不到++,只能得到C空格. 一开始我以为是没用urlencod ...

  2. 使用C6748和C5509A对nRF24L01驱动进行数据传输

    1. 写在前面 今天下午做了一个C5509A和C6748两个DSP的数据传输,经由RF24L01设备传输,都是模拟SPI协议,对于两个DSP来说,无非是配GPIO引脚,写好时序和延时.C5509A的G ...

  3. 谭浩强第四版第九章课后习题12>>>建立一个链表,每个节点包括:学号、姓名、性别、年龄。输入一个年龄,若链表 中的结点所包含的年龄等于此年龄,则删除此结点。

    #include<stdio.h> #include<stdlib.h> #define N sizeof(link) typedef struct lin { struct ...

  4. ansible结合SHELL搭建自己的CD持续交付系统

    一. 设计出发点 因公司业务面临频繁的迭代上线,一日数次.仅仅依靠手工效率过低且易出错. 考虑搭建一套可以满足现有场景的上线系统. 二 .为何采用ansible+shell方式 1.可控性(完全自主拥 ...

  5. 【jQuery】 选择器

    [jQuery] 选择器 资料: w3school  http://www.w3school.com.cn/jquery/jquery_ref_selectors.asp 1. 标签选择器 : $(& ...

  6. [网站日志]当Memcached缓存服务挂掉时性能监视器中的表现

    我们用的Memcached缓存服务是阿里云OCS,今天晚上遇到了一次OCS挂掉的情况(计划中的升级),看一下性能监视器中的表现,也许对分析黑色1秒问题有帮助. 应用日志中错误: 2014-06-05 ...

  7. Django admin源码剖析

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  8. Git 使用 粗糙记录

    版本控制应该是每一个开发人员应该会的东西,奈何,学校没有学习,随着写代码的时间的加长,越来月觉得版本控制的必要性了. 记得在实习的公司,同一痛的都是SVN. 至于GIt和SVN的区别,直接看连接 ht ...

  9. Python3 使用 logging.basicConfig() 配置输出日志中的中文乱码解决办法

    在源码中修改encoding='utf-8',因为 logging.basicConfig() 配置时实际上是用到了4大组件,只不过给了默认值而已,如果不知道怎么找到源码,告诉你们个快捷键,选中你lo ...

  10. 分布式文件系统---GlusterF

      1.1 分布式文件系统 1.1.1 什么是分布式文件系统 相对于本机端的文件系统而言,分布式文件系统(英语:Distributed file system, DFS),或是网络文件系统(英语:Ne ...