染色(bzoj 2243)
Description
给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作。
Input
第一行包含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)路径上的颜色段数量。
Output
对于每个询问操作,输出一行答案。
Sample Input
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
Sample Output
1
2
HINT
数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。
#include<cstdio>
#include<iostream>
#define N 100010
using namespace std;
int a[N],head[N],fa[N],son[N],dep[N],pos[N],top[N],lco[N*],rco[N*],sum[N*],tag[N*],n,m,sz;
struct node{
int to,pre;
};node e[N*];
void add(int i,int x,int y){
e[i].to=y;
e[i].pre=head[x];
head[x]=i;
}
void dfs1(int x){
son[x]=;
for(int i=head[x];i;i=e[i].pre){
int v=e[i].to;
if(fa[x]==v) continue;
fa[v]=x;dep[v]=dep[x]+;
dfs1(v);
son[x]+=son[v];
}
}
void dfs2(int x,int chain){
++sz;pos[x]=sz;top[x]=chain;int k=,maxn=;
for(int i=head[x];i;i=e[i].pre)
if(fa[x]!=e[i].to&&son[e[i].to]>maxn){
k=e[i].to;maxn=son[e[i].to];
}
if(!k) return;
dfs2(k,chain);
for(int i=head[x];i;i=e[i].pre)
if(fa[x]!=e[i].to&&e[i].to!=k)
dfs2(e[i].to,e[i].to);
}
void pushup(int k){
lco[k]=lco[k*];rco[k]=rco[k*+];
sum[k]=sum[k*]+sum[k*+];
if(rco[k*]==lco[k*+])sum[k]--;
}
void pushdown(int k){
if(!tag[k]) return;
tag[k*]=tag[k*+]=tag[k];
lco[k*]=lco[k*+]=tag[k];
rco[k*]=rco[k*+]=tag[k];
sum[k*]=sum[k*+]=;
tag[k]=;
}
void change(int l,int r,int k,int x,int y,int v){
if(l>=x&&r<=y){
tag[k]=lco[k]=rco[k]=v;
sum[k]=;
return;
}
pushdown(k);
int mid=l+r>>;
if(x<=mid) change(l,mid,k*,x,y,v);
if(y>mid) change(mid+,r,k*+,x,y,v);
pushup(k);
}
int query(int l,int r,int k,int x,int y){
if(l==x&&r==y)return sum[k];
pushdown(k);
int mid=l+r>>;
if(y<=mid) return query(l,mid,k*,x,y);
else if(x>mid) return query(mid+,r,k*+,x,y);
else {
int ans=query(l,mid,k*,x,mid)+query(mid+,r,k*+,mid+,y);
if(rco[k*]==lco[k*+]) ans--;
return ans;
}
}
int find(int l,int r,int k,int x){
if(l==r)return lco[k];
pushdown(k);
int mid=l+r>>;
if(x<=mid) return find(l,mid,k*,x);
else return find(mid+,r,k*+,x);
}
void xiugai(int x,int y,int v){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
change(,n,,pos[top[x]],pos[x],v);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
change(,n,,pos[x],pos[y],v);
}
int qiuhe(int x,int y){
int ans=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=query(,n,,pos[top[x]],pos[x]);
if(find(,n,,pos[fa[top[x]]])==find(,n,,pos[top[x]])) ans--;
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans+=query(,n,,pos[x],pos[y]);
return ans;
}
int main(){
freopen("jh.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=;i<n;i++){
int x,y;scanf("%d%d",&x,&y);
add(i*-,x,y);add(i*,y,x);
}
dfs1();dfs2(,);
for(int i=;i<=n;i++)change(,n,,pos[i],pos[i],a[i]);
char opt[];
for(int i=;i<=m;i++){
int x,y,v;
scanf("%s%d%d",opt,&x,&y);
if(opt[]=='C'){
scanf("%d",&v);
xiugai(x,y,v);
}
else printf("%d\n",qiuhe(x,y));
}
return ;
}
染色(bzoj 2243)的更多相关文章
- 洛谷 P2486 [SDOI2011]染色/bzoj 2243: [SDOI2011]染色 解题报告
[SDOI2011]染色 题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同 ...
- BZOJ 2243 染色 | 树链剖分模板题进阶版
BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...
- BZOJ 2243 染色(树链剖分好题)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 7971 Solved: 2990 [Submit][Stat ...
- [BZOJ 2243] [SDOI 2011] 染色 【树链剖分】
题目链接:BZOJ - 2243 题目分析 树链剖分...写了200+行...Debug了整整一天+... 静态读代码读了 5 遍 ,没发现错误,自己做小数据也过了. 提交之后全 WA . ————— ...
- BZOJ 2243: [SDOI2011]染色 [树链剖分]
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6651 Solved: 2432[Submit][Status ...
- bzoj 2243 [SDOI2011]染色(树链剖分,线段树)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4637 Solved: 1726[Submit][Status ...
- Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5020 Solved: 1872[Submit][Status ...
- bzoj 2243: [SDOI2011]染色 线段树区间合并+树链剖分
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 7925 Solved: 2975[Submit][Status ...
- bzoj 2243: [SDOI2011]染色 (树链剖分+线段树 区间合并)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9854 Solved: 3725[Submit][Status ...
- BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
随机推荐
- 用vscode开发vue应用[转]
https://segmentfault.com/a/1190000019055976 现在用VSCode开发Vue.js应用几乎已经是前端的标配了,但很多时候我们看到的代码混乱不堪,作为一个前端工程 ...
- CPP-基础:wchar_t
目 录 1简介 2例如 3将char转换成wchar_t 1.简介 wchar_t是C/C++的字符数据类型,是一种扩展的字符存储方式,wchar_t类型主要用在国际化程序的实现中,但它不等同于uni ...
- BZOJ1009: [HNOI2008]GT考试 (矩阵快速幂 + DP)
题意:求一个长度为n的数字字符串 (n <= 1e9) 不出现子串s的方案数 题解:用f i,j表示长度为i匹配到在子串j的答案 用kmp的失配函数预处理一下 然后这个转移每一个都是一样的 所以 ...
- MYSQL - 限制资源的使用
MYSQL - 限制资源的使用 1.MAX_QUERIES_PER_HOUR 用来限制用户每小时运行的查询数量 mysql> grant select on *.* to 'cu_blog'@' ...
- ASP.NET 开发人员不必担心 Node 的五大理由
哦别误会……我真的很喜欢 Node,而且我觉得它提出的概念和模式将在很长一段时间内,对服务端 Web 编程产生深远的影响.即使随着时间的推移 Node 过气了,我们肯定可以从下一个牛逼玩意身上或多或少 ...
- ios之UIImageView
UIImageView,顾名思义,是用来放置图片的.使用Interface Builder设计界面时,当然可以直接将控件拖进去并设置相关属性,这就不说了,这里讲的是用代码. 1.创建一个UIImage ...
- java面试宝典第三弹
Http和Https的区别 超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之 ...
- substring substr slice 区别
1. substring(start,end) 返回指定索引区间的字串,不改变原字符串 start 必需,开始位置的索引,一个非负的整数 end 可选,结束位置的索引(不包括其本身),如果未设置, ...
- 【OS_Linux】Linux系统中目录及文件管理
1.Linux系统中目录的树状结构 目录 /bin 存放二进制可执行文件(ls,cat,mkdir等),常用命令一般都在这里. /etc 存放系统管理和配置文件 /home 存放所有用户文件的根目录, ...
- perl学习之FLOCK函数的调用(讲的非常好)
一段演示flock系统调用的perl程序http://www.extmail.org/forum/viewthread.php?tid=1066