P2486 [SDOI2011]染色

题意:

题解:

与一般的树链剖分相比,不同点在于查询的不是路径上颜色的数量而是颜色段的数量
对于两个颜色段,112和221,两个颜色段数量都是2
如果合在一起颜色段的数量就是3,因为左边颜色段的右侧和右边颜色段的左侧是一样的颜色,合在一起后就成一段
所以本题其实就是将常规的区间求和改成这种特殊情况,在求完和的基础上,对左区间的最后一个颜色和右区间的第一个颜色进行判断,如果一样就减一

树剖中是把两点之间剖成了若干条链,所以我们还要解决不同的链之间的颜色重复问题,解决top[a]与fa[top[a]]颜色重复问题即可(如图)

总结一下:
就是判断所有接口处颜色是否一样

代码:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define lid (id << 1)
#define rid (id << 1) | 1
using namespace std;
int read(){int out = 0,flag = 1;char c = getchar();while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}return flag * out;}
const int maxn = 100019;
int num,na,nume,cnt;
int head[maxn];
struct Node{int v,nxt;
}E[maxn * 2];
void add(int u,int v){E[++nume].nxt = head[u];E[nume].v = v;head[u] = nume;}
int size[maxn],wson[maxn],dep[maxn],fa[maxn],top[maxn],pos[maxn],ori[maxn];
int col[maxn];
void dfs1(int id,int F){size[id] = 1;for(int i = head[id];i;i = E[i].nxt){int v = E[i].v;if(v == F)continue;dep[v] = dep[id] + 1;fa[v] = id;dfs1(v,id);size[id] += size[v];if(size[v] > size[wson[id]])wson[id] = v;}
}
void dfs2(int id,int TP){top[id] = TP;pos[id] = ++cnt;ori[cnt] = id;if(!wson[id])return ;dfs2(wson[id],TP);for(int i = head[id];i;i = E[i].nxt){int v = E[i].v;if(v == fa[id] || v == wson[id])continue;dfs2(v,v);}
}
int lc[maxn << 2];
int rc[maxn << 2];
struct sag_tree{int l,r;int sum,c;//区间颜色总数,叶子颜色int lazy;//儿子的颜色
}tree[maxn << 2];
void pushup(int id)
{tree[id].sum = tree[lid].sum + tree[rid].sum;if(rc[lid] == lc[rid])tree[id].sum -= 1;//如果连接处颜色一样,减一 lc[id] = lc[lid];rc[id] = rc[rid];
}
void build(int id,int l,int r){tree[id].l = l;tree[id].r = r;if(l == r){tree[id].c = col[ori[l]];//赋值:叶子颜色lc[id] = rc[id] = col[ori[l]];//赋值:区间左颜色和区间右颜色tree[id].sum = 1;//颜色数为1return ;}int mid = l + r >> 1;build(lid,l,mid);build(rid,mid + 1,r);pushup(id);
}
void pushdown(int id){if(tree[id].lazy != 0 && tree[id].l != tree[id].r){int c = tree[id].lazy;tree[lid].lazy = tree[rid].lazy = c;//粉刷tree[lid].c = tree[rid].c = c;lc[lid] = rc[lid] = lc[rid] = rc[rid] = c;//更新左右tree[lid].sum = tree[rid].sum = 1;//粉刷完以后只有一种颜色了tree[id].lazy = 0;}
}
void update(int id,int c,int l,int r){pushdown(id);if(tree[id].l == l && tree[id].r == r){tree[id].c = c;//更新颜色 tree[id].lazy = c;tree[id].sum = 1;//此时区间内只有一种颜色  lc[id] = rc[id] = c;return ;}int mid = tree[id].l + tree[id].r >> 1;if(mid < l){update(rid,c,l,r);}else if(mid >= r){update(lid,c,l,r);}else{update(lid,c,l,mid);update(rid,c,mid + 1,r);}pushup(id);
}
int query(int id,int l,int r)//查询区间颜色数量
{pushdown(id);if(tree[id].l == l && tree[id].r == r){return tree[id].sum;}int mid = tree[id].l + tree[id].r >> 1;if(mid < l){return query(rid,l,r);}else if(mid >= r){return query(lid,l,r);}else{int ret = query(lid,l,mid) + query(rid,mid + 1,r);if(rc[lid] == lc[rid])ret -= 1;//如果连接处颜色一样 return ret;}
}
int Qc(int id,int l,int r){//查询单点的颜色pushdown(id);if(tree[id].l == l && tree[id].r == r){return tree[id].c;}int mid = tree[id].l + tree[id].r >> 1;if(mid < l)return Qc(rid,l,r);else return Qc(lid,l,r);
}
void uprange(int x,int y,int c){while(top[x] != top[y]){if(dep[top[x]] < dep[top[y]])swap(x,y);update(1,c,pos[top[x]],pos[x]);x = fa[top[x]];}if(dep[x] > dep[y])swap(x,y);update(1,c,pos[x],pos[y]);
}
int Qsum(int x,int y){int ans = 0,Cson,Cfa;//儿子的颜色,爸爸的颜色while(top[x] != top[y]){if(dep[top[x]] < dep[top[y]])swap(x,y);ans += query(1,pos[top[x]],pos[x]);Cson = Qc(1,pos[top[x]],pos[top[x]]);Cfa = Qc(1,pos[fa[top[x]]],pos[fa[top[x]]]);if(Cson == Cfa)ans -= 1;x = fa[top[x]];}if(dep[x] > dep[y])swap(x,y);ans += query(1,pos[x],pos[y]);return ans;
}
int main(){num = read();na = read();for(int i = 1;i <= num;i++)col[i] = read();int u,v;for(int i = 1;i <= num - 1;i++){u = read();v = read();add(u,v);add(v,u);}dfs1(1,-1);dfs2(1,1);build(1,1,num);char ask;int c;for(int i = 1;i <= na;i++){cin>>ask;if(ask == 'Q'){u = read();v = read();printf("%d\n",Qsum(u,v));}else{u = read();v = read();c = read();uprange(u,v,c);}}return 0;}

P2486 [SDOI2011]染色相关推荐

  1. 洛谷 P2486 [SDOI2011]染色 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 PushDown与Update Q AC代码 总结与拓展 题面 题目链接 P2486 ...

  2. 洛谷 P2486 [SDOI2011]染色 LCT

    Code: #include <cstdio> //SDOI2010 染色 #include <algorithm> #include <cstring> #inc ...

  3. P2486 [SDOI2011]染色(树链剖分+线段树)

    题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 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 ...

  4. 洛谷P2486 [SDOI2011]染色(树链剖分+线段树判断边界)

    [题目链接] [思路]: 涉及到树上区间修改操作,所以使用树链剖分,涉及到区间查询,所以使用线段树. update操作时,就正常操作,难点在于query操作的计数. 因为树链剖分的dfs序只能保证一条 ...

  5. [Luogu 2486] SDOI2011 染色

    [Luogu 2486] SDOI2011 染色 树剖水题,线段树维护. 详细题解不写了. 我只想说我写的线段树又变漂亮了qwq #include <algorithm> #include ...

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

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

  7. BZOJ 2243: [SDOI2011]染色

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

  8. [SDOI2011]染色

    题目:染色 传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 分析: (1)很裸的树链剖分,然而我忘了树剖怎么打(其实是代码太长不想打, ...

  9. 【BZOJ2243】 [SDOI2011]染色

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

最新文章

  1. 小程序使用富文本完整代码及示例图
  2. QIIME 2教程. 27语义类型Semantic(2020.11)
  3. kafka的安装与启动运行
  4. 原 记录一下iOS开发中琐碎的点点_6
  5. opencv中的CommandLineParser类用法
  6. 150名打工人被AI判定“效率低”遭开除,网友:属实是人工智能,能治工人
  7. CCF 2019年题目题解 - Python
  8. php上传手机文件到服务器,安卓上传文件至PHP服务器(示例代码)
  9. for循环批量写文件 shell_shell之for循环的3个简单脚本
  10. 哪里下载linux内核补丁,给大家科普一下linux内核补丁,顺便说一下华为的事
  11. cam350 不能打开光绘文件_CAM350使用教程-复制Gerber层
  12. 让自己的网站变成暗黑模式
  13. 转载:Python正则表达式
  14. wamp怎么安装mysql服务器_使用WAMPServer套件可安装Apache服务器和MySQL服务器
  15. python手册中文版-Python中文文档
  16. 什么是LoRa协议?
  17. 吉林警察学院计算机考研,吉林警察学院怎么样
  18. python操作word文档,合并
  19. 【Opencv】图像分割——区域生长
  20. html table相同值合并单元格,ElementUI表格列相同值自动合并单元格( 单列 )

热门文章

  1. 世界上最诡异的画,到底为何让无数人闻风丧胆?
  2. 其实你女朋友也不是很爱你...
  3. 住宅按套内面积算,医院人脸识别黄牛,DNA碱基对可能会扩充,菜鸟发布供应链系统,猪瘟不影响食品安全,这就是今天的大新闻...
  4. 隐藏在数学中的哲理,令人回味无穷
  5. 【直观理解】一文搞懂RNN(循环神经网络)基础篇
  6. 微型计算机名词术语,微型计算机及接口技名词解释题及解答题.doc
  7. python 多分类情感_python 文本情感分类
  8. android fragmentstatepageradapter框架,安卓爬坑指南之FragmentStatePagerAdapter
  9. python ctp接口_使用ctp的python接口
  10. golang防止MySQL注入_mysql – 如何最大限度地降低golang服务中下游服务中SQL注入的风险?...