bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 9012 Solved: 3375
[Submit][Status][Discuss]
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
6 5
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
3
1
2
HINT
数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。
Source
树链剖分+线段树
操作还是常规的区间修改 但是要注意区间合并的时候,颜色段数量的合并
在树的路径上合并区间时,有点不好处理区间左右端点,于
是我们把u->v拆成u->lca lca->v
这样区间更新端点就是同向的,即每次查询可以把一端统一地作为更新端点
由于u->lca lca->v左右端点必定重合 所以 最后答案减一
sb的我update忘了pushup调了1h
- #include<cstdio>
- #include<iostream>
- #include<algorithm>
- #include<cstring>
- #define ls u<<1
- #define rs ls|1
- #define ll long long
- #define N 100050
- using namespace std;
- int n,m,tot,cnt,a[N],fa[N][20],tp[N],siz[N],hd[N];
- int dep[N],tid[N],son[N],v[N];
- struct edge{int v,next;}e[N<<1];
- struct node{int l,r,sum,lz;}t[N<<2];
- void adde(int u,int v){
- e[++tot].v=v;
- e[tot].next=hd[u];
- hd[u]=tot;
- }
- void dfs1(int u,int pre){
- dep[u]=dep[pre]+1;fa[u][0]=pre;siz[u]=1;
- for(int j=1;(1<<j)<dep[u];j++)
- fa[u][j]=fa[fa[u][j-1]][j-1];
- for(int i=hd[u];i;i=e[i].next){
- int v=e[i].v;
- if(v==pre)continue;
- dfs1(v,u);siz[u]+=siz[v];
- if(siz[v]>siz[son[u]])son[u]=v;
- }
- }
- void dfs2(int u,int anc){
- if(!u)return;
- tid[u]=++cnt;v[cnt]=a[u];tp[u]=anc;
- dfs2(son[u],anc);
- for(int i=hd[u];i;i=e[i].next){
- int v=e[i].v;
- if(v==fa[u][0]||v==son[u])continue;
- dfs2(v,v);
- }
- }
- int lca(int x,int y){
- if(x==y)return x;
- if(dep[x]<dep[y])swap(x,y);
- for(int i=18;~i;i--)
- if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
- if(x==y)return x;
- for(int i=18;~i;i--){
- if(fa[x][i]==fa[y][i])continue;
- x=fa[x][i];y=fa[y][i];
- }
- return fa[x][0];
- }
- void pushup(int u){
- t[u].sum=t[ls].sum+t[rs].sum;
- t[u].l=t[ls].l;t[u].r=t[rs].r;
- if(t[ls].r==t[rs].l)t[u].sum--;
- }
- void pushdown(int u){
- if(t[u].lz==-1)return;
- t[ls].l=t[ls].r=t[ls].lz=t[u].lz;
- t[rs].l=t[rs].r=t[rs].lz=t[u].lz;
- t[ls].sum=t[rs].sum=1;
- t[u].lz=-1;
- }
- void build(int u,int l,int r){
- t[u].lz=-1;
- if(l==r){
- t[u].l=t[u].r=v[l];
- t[u].sum=1;return;
- }
- int mid=l+r>>1;
- build(ls,l,mid);
- build(rs,mid+1,r);
- pushup(u);
- }
- node query(int u,int L,int R,int l,int r){
- if(l<=L&&R<=r)return t[u];
- pushdown(u);node ret;
- int mid=L+R>>1,fg=0;
- if(l<=mid)ret=query(ls,L,mid,l,r),fg=1;
- if(r>mid){
- node tmp=query(rs,mid+1,R,l,r);
- if(!fg)ret=tmp;
- else{
- ret.sum+=tmp.sum;
- if(ret.r==tmp.l)ret.sum--;
- ret.r=tmp.r;
- }
- }
- return ret;
- }
- void update(int u,int L,int R,int l,int r,int c){
- if(l<=L&&R<=r){
- t[u].lz=t[u].l=t[u].r=c;
- t[u].sum=1;return;
- }
- pushdown(u);
- int mid=L+R>>1;
- if(l<=mid)update(ls,L,mid,l,r,c);
- if(r>mid)update(rs,mid+1,R,l,r,c);
- pushup(u);
- }
- node jump(int x,int y,int val,int op){
- int fx=tp[x],fy=tp[y];node ret;
- ret.l=ret.r=ret.sum=0;
- while(fx!=fy){
- if(op)update(1,1,cnt,tid[fx],tid[x],val);
- else{
- node tmp=query(1,1,cnt,tid[fx],tid[x]);
- ret.sum+=tmp.sum;
- if(tmp.r==ret.l)ret.sum--;
- ret.l=tmp.l;
- }
- x=fa[fx][0];fx=tp[x];
- }
- if(dep[x]>dep[y])swap(x,y);
- if(op)update(1,1,cnt,tid[x],tid[y],val);
- else{
- node tmp=query(1,1,cnt,tid[x],tid[y]);
- ret.sum+=tmp.sum;
- if(tmp.r==ret.l)ret.sum--;
- ret.l=tmp.l;
- }
- return ret;
- }
- int main(){
- scanf("%d%d",&n,&m);
- for(int i=1;i<=n;i++)
- scanf("%d",&a[i]);
- for(int i=1;i<n;i++){
- int a,b;
- scanf("%d%d",&a,&b);
- adde(a,b);adde(b,a);
- }
- dfs1(1,0);dfs2(1,1);
- build(1,1,cnt);
- int x,y,c;char s[2];
- while(m--){
- scanf("%s%d%d",s,&x,&y);
- int anc=lca(x,y);
- if(s[0]=='C'){
- scanf("%d",&c);
- jump(x,anc,c,1);
- jump(y,anc,c,1);
- }
- else{
- node t1,t2;
- t1=jump(x,anc,0,0);
- t2=jump(y,anc,0,0);
- printf("%d\n",t1.sum+t2.sum-1);
- }
- }
- return 0;
- }
bzoj2243[SDOI2011]染色 树链剖分+线段树的更多相关文章
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)
题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...
- B20J_2243_[SDOI2011]染色_树链剖分+线段树
B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...
- 2243: [SDOI2011]染色 树链剖分+线段树染色
给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- 【bzoj1959】[Ahoi2005]LANE 航线规划 树链剖分+线段树
题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系——一个巨大的由千百万星球构成的Samuel星系. 星际空间站的Samuel II巨型计算 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
随机推荐
- 原始的Ajax方法 (异步的 JavaScript 和 XML -- (Extensible Markup Language 可扩展标记语言))
<script language="javascript" type="text/javascript"> var request = false; ...
- JAVA_SE基础——71.Random类制作随机验证码
public class Demo5 { public static void main(String[] args) { char[] arr={'s','b','g','h','a','c'}; ...
- NFS PersistentVolume - 每天5分钟玩转 Docker 容器技术(151)
上一节我们介绍了 PV 和 PVC,本节通过 NFS 实践. 作为准备工作,我们已经在 k8s-master 节点上搭建了一个 NFS 服务器,目录为 /nfsdata: 下面创建一个 PV mypv ...
- Python 黑客相关电子资源和书籍推荐
原创 2017-06-03 玄魂工作室 玄魂工作室 继续上一次的Python编程入门的资源推荐,本次为大家推荐的是Python网络安全相关的资源和书籍. 在去年的双11送书的时候,其实送过几本Pyth ...
- "双非"应届生校招如何获得大厂青睐?(内附技术岗超全求职攻略)
写在前面的话 笔者从17年的2月份开始准备春招,其中遇到不少坑,也意识到自己走过的弯路.故写了这篇文章总结一番,本文适合主动学习的,对自己要学的课程不明确的,对面试有恐惧症的...等将来打算从事技术岗 ...
- spark2.1:在RDD[unit].foreach(s=>{})内部调用sparkSession对象抛出NullPointException
问题代码: val sample_data_combine_result=List( (0,(List(FitModel(4022,1447.92,-8.38983306721434,2.0),Fit ...
- hdu1222&hdu1014 循环群的生成元
hdu1222 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1222 题目大意: 大灰狼追小白兔.小白兔可以躲起来的洞绕成一个圈,大灰狼从0这个点出 ...
- .Net中集合排序还可以这么玩
背景: public class StockQuantity { public StockQuantity(string status, DateTime dateTime, int quantity ...
- Docker下ETCD集群搭建
搭建集群之前首先准备两台安装了CentOS 7的主机,并在其上安装好Docker. Master 10.100.97.46 Node 10.100.97.64 ETCD集群搭建有三种方式,分别是Sta ...
- C#之设计模式之六大原则(转载)
设计模式之六大原则(转载) 关于设计模式的六大设计原则的资料网上很多,但是很多地方解释地都太过于笼统化,我也找了很多资料来看,发现CSDN上有几篇关于设计模式的六大原则讲述的比较通俗易懂,因此转载过来 ...