题意

对一个树上维护两种操作,一种是把x到y间的点都染成c色,另一种是求x到y间的点有多少个颜色块,比如112221由“11”,“222”,“1”三块组成。

思路

这题的关键是要如何维护这个颜色块,我们可以利用线段树,记录每个区间的块数,区间左端点,区间右端点的颜色。合并中如果两个区间相邻点颜色相同,个数要减去1.
查询也是一样的,链与链间的相邻点也要考虑清楚。

  1. #include <algorithm>
  2. #include <iterator>
  3. #include <iostream>
  4. #include <cstring>
  5. #include <cstdlib>
  6. #include <iomanip>
  7. #include <bitset>
  8. #include <cctype>
  9. #include <cstdio>
  10. #include <string>
  11. #include <vector>
  12. #include <stack>
  13. #include <cmath>
  14. #include <queue>
  15. #include <list>
  16. #include <map>
  17. #include <set>
  18. #include <cassert>
  19.  
  20. /*
  21.  
  22. ⊂_ヽ
  23.   \\ Λ_Λ 来了老弟
  24.    \('ㅅ')
  25.     > ⌒ヽ
  26.    /   へ\
  27.    /  / \\
  28.    レ ノ   ヽ_つ
  29.   / /
  30.   / /|
  31.  ( (ヽ
  32.  | |、\
  33.  | 丿 \ ⌒)
  34.  | |  ) /
  35. 'ノ )  Lノ
  36.  
  37. */
  38.  
  39. using namespace std;
  40. #define lson (l , mid , rt << 1)
  41. #define rson (mid + 1 , r , rt << 1 | 1)
  42. #define debug(x) cerr << #x << " = " << x << "\n";
  43. #define pb push_back
  44. #define pq priority_queue
  45.  
  46. typedef long long ll;
  47. typedef unsigned long long ull;
  48. //typedef __int128 bll;
  49. typedef pair<ll ,ll > pll;
  50. typedef pair<int ,int > pii;
  51. typedef pair<int,pii> p3;
  52.  
  53. //priority_queue<int> q;//这是一个大根堆q
  54. //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
  55. #define fi first
  56. #define se second
  57. //#define endl '\n'
  58.  
  59. #define boost ios::sync_with_stdio(false);cin.tie(0)
  60. #define rep(a, b, c) for(int a = (b); a <= (c); ++ a)
  61. #define max3(a,b,c) max(max(a,b), c);
  62. #define min3(a,b,c) min(min(a,b), c);
  63.  
  64. const ll oo = 1ll<<;
  65. const ll mos = 0x7FFFFFFF; //
  66. const ll nmos = 0x80000000; //-2147483648
  67. const int inf = 0x3f3f3f3f;
  68. const ll inff = 0x3f3f3f3f3f3f3f3f; //
  69. const ll mod = ;
  70. const double esp = 1e-;
  71. const double PI=acos(-1.0);
  72. const double PHI=0.61803399; //黄金分割点
  73. const double tPHI=0.38196601;
  74.  
  75. template<typename T>
  76. inline T read(T&x){
  77. x=;int f=;char ch=getchar();
  78. while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
  79. while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
  80. return x=f?-x:x;
  81. }
  82.  
  83. inline void cmax(int &x,int y){if(x<y)x=y;}
  84. inline void cmax(ll &x,ll y){if(x<y)x=y;}
  85. inline void cmin(int &x,int y){if(x>y)x=y;}
  86. inline void cmin(ll &x,ll y){if(x>y)x=y;}
  87.  
  88. /*-----------------------showtime----------------------*/
  89.  
  90. const int maxn = 1e5+;
  91. int a[maxn],b[maxn];
  92. int dp[maxn],sz[maxn],fa[maxn],son[maxn];
  93. vector<int>mp[maxn];
  94.  
  95. void dfs1(int u,int f,int deep){
  96. dp[u] = deep;
  97. fa[u] = f;
  98. sz[u] = ;
  99. int mx = ;
  100. for(int i=; i<mp[u].size(); i++){
  101. int v = mp[u][i];
  102. if(v == f) continue;
  103. dfs1(v, u, deep+);
  104. sz[u] += sz[v];
  105. if(sz[v] > mx) {mx = sz[v], son[u] = v;}
  106. }
  107. }
  108.  
  109. int top[maxn],id[maxn],cnt = ;
  110. void dfs2(int u,int f,int topf){
  111. top[u] = topf;
  112. id[u] = ++cnt;
  113. b[cnt] = a[u];
  114. if(son[u])dfs2(son[u], u, topf);
  115. for(int i=; i<mp[u].size(); i++){
  116. int v = mp[u][i];
  117. if(v == f || v == son[u]) continue;
  118. dfs2(v, u, v);
  119. }
  120. }
  121.  
  122. int tag[maxn<<],lazy[maxn<<],ly[maxn<<],rz[maxn<<];
  123. void pushup(int rt){
  124. tag[rt] = tag[rt<<] + tag[rt<<|];
  125. rz[rt] = rz[rt<<];
  126. ly[rt] = ly[rt<<|];
  127. if(ly[rt<<] == rz[rt<<|])tag[rt] --;
  128. }
  129. void build(int l,int r,int rt){
  130. if(l == r){
  131. tag[rt] = ;
  132. ly[rt] = rz[rt] = b[l];
  133. return ;
  134. }
  135. int mid = (l + r) >> ;
  136. build(l, mid, rt<<);
  137. build(mid+,r,rt<<|);
  138. pushup(rt);
  139. // cout<<l<<" "<<r<<" "<<rz[rt] << " " << ly[rt]<<endl;
  140. }
  141. void pushdown(int l,int r,int rt){
  142. tag[rt<<] = tag[rt<<|] = ;
  143. ly[rt<<] = rz[rt<<] = lazy[rt];
  144. ly[rt<<|] = rz[rt<<|] = lazy[rt];
  145. lazy[rt<<] = lazy[rt<<|] = lazy[rt];
  146. lazy[rt] = ;
  147. }
  148. void update(int L, int R, int c, int l, int r,int rt){
  149. if(l >= L && r <= R){
  150. tag[rt] = ;
  151. ly[rt] = rz[rt] = c;
  152. lazy[rt] = c;
  153. return;
  154. }
  155. int mid = (l + r) >> ;
  156. if(lazy[rt]) pushdown(l, r, rt);
  157. if(mid >= L) update(L, R, c, l, mid, rt<<);
  158. if(mid < R) update(L,R,c,mid+,r,rt<<|);
  159. pushup(rt);
  160. }
  161. int n,m;
  162. void solve(int x,int y,int c){
  163. while(top[x] != top[y]){
  164. if(dp[top[x]] < dp[top[y]]) swap(x, y);
  165. update(id[top[x]], id[x], c, , n, );
  166. x = fa[top[x]];
  167. }
  168. if(dp[x] > dp[y]) swap(x, y);
  169. update(id[x], id[y], c, , n, );
  170. }
  171.  
  172. int query(int L,int R, int l,int r,int rt,int &tmpl,int &tmpr){
  173. if(l >= L && r<= R){
  174. if(l == L) tmpl = rz[rt];
  175. if(r == R) tmpr = ly[rt];
  176.  
  177. return tag[rt];
  178. }
  179. int mid = (l + r) >> ;
  180. if(lazy[rt])pushdown(l, r, rt);
  181. int res = ;
  182. int ql = -, qr = -;
  183. if(mid >= L) {
  184. res += query(L, R, l, mid, rt<<,tmpl,tmpr);
  185. ql = ly[rt<<];
  186. }
  187. if(mid < R){
  188. res += query(L, R, mid +, r, rt<<|,tmpl,tmpr);
  189. qr = rz[rt<<|];
  190. }
  191. if(ql == qr && ql != -) res --;
  192. pushup(rt);
  193. return res;
  194. }
  195. int cal(int x,int y){
  196. int res = ,lax = -,lay=-;
  197.  
  198. while(top[x] != top[y]){
  199. int tmpl = -,tmpr=-;
  200. if(dp[top[x]] > dp[top[y]]) {
  201. res += query(id[top[x]], id[x], , n, , tmpl, tmpr);//tmp,flag 1,r
  202. if(lax == tmpr) res--;
  203. lax = tmpl;
  204. x = fa[top[x]];
  205. }
  206. else {
  207. res += query(id[top[y]], id[y], , n, ,tmpl,tmpr);
  208. if(lay == tmpr) res--;
  209. lay = tmpl;
  210. y = fa[top[y]];
  211. }
  212.  
  213. // cout<<tmpl<<" !! "<<tmpr<<endl;
  214. }
  215.  
  216. if(dp[x] > dp[y]){
  217. int tmpl = -,tmpr=-;
  218. res += query(id[y], id[x], , n, ,tmpl,tmpr);
  219. if(tmpr == lax) res--;
  220. if(tmpl == lay) res--;
  221. }
  222. else {
  223. int tmpl = -,tmpr=-;
  224. res += query(id[x], id[y], , n, ,tmpl,tmpr);
  225. if(tmpl == lax) res--;
  226. if(tmpr == lay) res--;
  227. }
  228.  
  229. return res;
  230. }
  231. int main(){
  232. scanf("%d%d", &n, &m);
  233. rep(i, , n) scanf("%d", &a[i]);
  234. rep(i, , n-) {
  235. int u,v;
  236. scanf("%d%d", &u, &v);
  237. mp[u].pb(v);
  238. mp[v].pb(u);
  239. }
  240. dfs1(, , );
  241. dfs2(, , );
  242. build(, n, );
  243.  
  244. while(m--){
  245. char str[];
  246. scanf("%s", str);
  247. if(str[] == 'C') {
  248. int x,y,z;
  249. scanf("%d%d%d", &x, &y, &z);
  250. solve(x, y, z);
  251. }
  252. else {
  253. int x,y;
  254. scanf("%d%d", &x, &y);
  255. printf("%d\n", cal (x,y));
  256. }
  257.  
  258. }
  259. return ;
  260. }

P2486 [SDOI2011]染色 维护区间块数 树链剖分的更多相关文章

  1. bzoj 2243: [SDOI2011]染色 线段树区间合并+树链剖分

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 7925  Solved: 2975[Submit][Status ...

  2. P2486 [SDOI2011]染色 区间合并+树链剖分(加深对线段树的理解)

    #include<bits/stdc++.h> using namespace std; ; struct node{ int l,r,cnt,lazy; node(,,,):l(l1), ...

  3. P2486 [SDOI2011]染色 区间合并+树链剖分(加深对线段树的理解)

    #include<bits/stdc++.h> using namespace std; ; struct node{ int l,r,cnt,lazy; node(,,,):l(l1), ...

  4. 2020牛客NOIP赛前集训营-提高组(第三场) C - 牛半仙的妹子Tree (树链剖分)

    昨天教练问我:你用树剖做这道题,怎么全部清空状态呢?    我:???不是懒标记就完了???    教练:树剖不是要建很多棵线段树吗,不止log个,你要一个一个清?    我:为什么要建很多棵线段树? ...

  5. luogu题解 P3950部落冲突--树链剖分

    题目链接 https://www.luogu.org/problemnew/show/P3950 分析 大佬都用LCT,我太弱只会树链剖分 一个很裸的维护边权树链剖分题.按照套路,对于一条边\(< ...

  6. Luogu P2486 [SDOI2011]染色(树链剖分+线段树合并)

    Luogu P2486 [SDOI2011]染色 题面 题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例: 6 5 2 2 1 2 1 1 1 ...

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

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

  8. bzoj 2243: [SDOI2011]染色 (树链剖分+线段树 区间合并)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9854  Solved: 3725[Submit][Status ...

  9. P2486 [SDOI2011]染色(树剖)区间覆盖+区间的连续段

    https://www.luogu.org/problemnew/show/P2486 值的一看https://www.cnblogs.com/Tony-Double-Sky/p/9283262.ht ...

随机推荐

  1. UE4 代理 BindRaw和BindUObject

    代理允许您在C++对象上以通用的但类型安全的方式调用成员函数.通过使用代理,可以将其动态地绑定到任何对象的成员函数上,然后在该对象上调用函数,即时调用者不知道该对象的类型也没关系. 任何时候都应该通过 ...

  2. 续集:白菜的内涵,更新nand分区为ubifs,替换overlay

    在上一篇真千兆路由的极限之OPENWRT MAKE, 某品牌白菜价QCA9558/QCA9880/QCA8337N纯种组合OS搭建时记中附带了128M nand的空间图示,在ar71xx profil ...

  3. EasyUI combobox下拉列表实现搜索过滤(模糊匹配)

    项目中的某个下拉列表长达200多个项,这么巨大的数量一个一个找眼镜都得看花,于是就得整了个搜索功能.看网上别人帖子有只能前缀匹配的方案,但只能前缀匹配的话用起来也不是很方便.于是就记录一下模糊匹配的方 ...

  4. oracle的开窗函数

    原创 select * from (select province, commodity, sum(price), ROW_NUMBER() OVER(PARTITION BY province  o ...

  5. JVM内存结构 VS Java内存模型 VS Java对象模型

    前面几篇文章中, 系统的学习了下JVM内存结构.Java内存模型.Java对象模型, 但是发现自己还是对这三者的概念和区别比较模糊, 傻傻分不清楚.所以就有了这篇文章, 本文主要是对这三个技术点再做一 ...

  6. Filebeat6.3文档—Log input配置

    Filebeat6.3文档-Log input配置 paths 日志加载的路径.例如加载某一子目录级别下面路径的日志:/var/log/*/*.log.这表示会去加载以.log结尾的/var/log下 ...

  7. Unity经典游戏教程之:合金弹头

    版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...

  8. java中线程安全,线程死锁,线程通信快速入门

    一:多线程安全问题 ###1 引入 /* * 多线程并发访问同一个数据资源 * 3个线程,对一个票资源,出售 */ public class ThreadDemo { public static vo ...

  9. 通过jmeter发送webservice接口请求

    1.webservice接口地址:http://ip:port/...?wsdl 2.接口数据类型:<cuxGmiChukuRmaTrxV><salesrepId xmlns:xsi ...

  10. Java泛型使用的简单介绍

    目录 一. 泛型是什么 二. 使用泛型有什么好处 三. 泛型类 四. 泛型接口 五. 泛型方法 六. 限定类型变量 七. 泛型通配符 7.1 上界通配符 7.2 下界通配符 7.3 无限定通配符 八. ...