LCT的一种姿势。

题意:给定一棵树。每次把一条路径上的点染成一种颜色,求一条路径上有多少段颜色。

解:

首先可以很轻易的用树剖解决,只不过代码量让人望而却步...

有一种难以想象的LCT做法...

记录每个点的颜色,修改用lazy tag

询问时把那一条链split出来,pushup的时候看当前点和前驱/后继的颜色是否相同。如果不同就sum++,表示有一条连接不同颜色点的边。

最后的sum就是连接不同颜色的点的边数,再加1就是段数了。

  1 #include <cstdio>
  2 #include <algorithm>
  3
  4 const int N = 100010;
  5
  6 int fa[N], s[N][2], col[N], sum[N], lc[N], rc[N], S[N], Sp, tag[N];
  7 bool rev[N];
  8
  9 inline bool no_root(int x) {
 10     return (s[fa[x]][0] == x) || (s[fa[x]][1] == x);
 11 }
 12
 13 inline void pushdown(int x) {
 14     int ls = s[x][0], rs = s[x][1];
 15     if(rev[x]) {
 16         if(ls) {
 17             rev[ls] ^= 1;
 18             std::swap(lc[ls], rc[ls]);
 19         }
 20         if(rs) {
 21             rev[rs] ^= 1;
 22             std::swap(lc[rs], rc[rs]);
 23         }
 24         std::swap(s[x][0], s[x][1]);
 25         rev[x] = 0;
 26     }
 27     if(tag[x]) {
 28         int c = tag[x];
 29         if(ls) {
 30             tag[ls] = col[ls] = lc[ls] = rc[ls] = c;
 31             sum[ls] = 0;
 32         }
 33         if(rs) {
 34             tag[rs] = col[rs] = lc[rs] = rc[rs] = c;
 35             sum[rs] = 0;
 36         }
 37         tag[x] = 0;
 38     }
 39     return;
 40 }
 41
 42 inline void pushup(int x) {
 43     int ls = s[x][0], rs = s[x][1];
 44     pushdown(ls);
 45     pushdown(rs);
 46     sum[x] = sum[ls] + sum[rs];
 47     if(ls) {
 48         lc[x] = lc[ls];
 49         if(rc[ls] != col[x]) {
 50             sum[x]++;
 51         }
 52     }
 53     else {
 54         lc[x] = col[x];
 55     }
 56     if(rs) {
 57         rc[x] = rc[rs];
 58         if(lc[rs] != col[x]) {
 59             sum[x]++;
 60         }
 61     }
 62     else {
 63         rc[x] = col[x];
 64     }
 65     return;
 66 }
 67
 68 inline void rotate(int x) {
 69     int y = fa[x];
 70     int z = fa[y];
 71     bool f = (s[y][1] == x);
 72
 73     fa[x] = z;
 74     if(no_root(y)) {
 75         s[z][s[z][1] == y] = x;
 76     }
 77     s[y][f] = s[x][!f];
 78     if(s[x][!f]) {
 79         fa[s[x][!f]] = y;
 80     }
 81     s[x][!f] = y;
 82     fa[y] = x;
 83
 84     pushup(y);
 85     pushup(x);
 86     return;
 87 }
 88
 89 inline void splay(int x) {
 90     int y = x;
 91     S[++Sp] = y;
 92     while(no_root(y)) {
 93         y = fa[y];
 94         S[++Sp] = y;
 95     }
 96     while(Sp) {
 97         pushdown(S[Sp]);
 98         Sp--;
 99     }
100
101     y = fa[x];
102     int z = fa[y];
103     while(no_root(x)) {
104         if(no_root(y)) {
105             (s[z][1] == y) ^ (s[y][1] == x) ?
106             rotate(x) : rotate(y);
107         }
108         rotate(x);
109         y = fa[x];
110         z = fa[y];
111     }
112     return;
113 }
114
115 inline void access(int x) {
116     int y = 0;
117     while(x) {
118         splay(x);
119         s[x][1] = y;
120         pushup(x);
121         y = x;
122         x = fa[x];
123     }
124     return;
125 }
126
127 inline void make_root(int x) {
128     access(x);
129     splay(x);
130     rev[x] = 1;
131     return;
132 }
133
134 inline int find_root(int x) {
135     access(x);
136     splay(x);
137     while(s[x][0]) {
138         x = s[x][0];
139         pushdown(x);
140     }
141     return x;
142 }
143
144 inline void link(int x, int y) {
145     make_root(x);
146     fa[x] = y;
147     return;
148 }
149
150 inline void cut(int x, int y) {
151     make_root(x);
152     access(y);
153     splay(y);
154     fa[x] = s[y][0] = 0;
155     pushup(y);
156     return;
157 }
158
159 inline void change(int x, int y, int c) {
160     make_root(x);
161     access(y);
162     splay(y);
163     tag[y] = col[y] = lc[y] = rc[y] = c;
164     sum[y] = 0;
165     return;
166 }
167
168 inline int ask(int x, int y) {
169     make_root(x);
170     access(y);
171     splay(y);
172     return sum[y] + 1;
173 }
174
175 char str[10];
176
177 int main() {
178     int n, m;
179     scanf("%d%d", &n, &m);
180     for(int i = 1; i <= n; i++) {
181         scanf("%d", &col[i]);
182         lc[i] = rc[i] = col[i];
183     }
184     for(int i = 1, x, y; i < n; i++) {
185         scanf("%d%d", &x, &y);
186         link(x, y);
187     }
188
189     for(int i = 1, x, y, z; i <= m; i++) {
190         scanf("%s%d%d", str, &x, &y);
191         if(str[0] == 'C') {
192             scanf("%d", &z);
193             change(x, y, z);
194         }
195         else {
196             int t = ask(x, y);
197             printf("%d\n", t);
198         }
199     }
200
201     return 0;
202 }

AC代码

有个简化版的问题:给定根,每次修改/询问必有一端点是根。有一种解法是,染色access,查询就看要跳多少个虚边。但是这样会被链卡成n²...不知道怎么改进。

转载于:https://www.cnblogs.com/huyufeifei/p/10170584.html

洛谷P2486 染色相关推荐

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

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

  2. 洛谷 P2486 [SDOI2011]染色 LCT

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

  3. 染色(树链剖分 洛谷-P2486)

    文章目录 题目描述 解析 代码 thanks for reading! 传送门 首先,对hash学姐对本题拔刀相助的debug行为表示衷心的感谢 题目描述 解析 用线段树维护颜色序列个数.最左颜色与最 ...

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

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

  5. 洛谷P2486 lct做法

    题意: 给出一颗nnn个结点的无根树,处理mmm个操作,每个操作只会是如下两种之一: (1)将结点aaa到bbb的路径上的所有点染成颜色kkk (2)询问结点aaa到结点bbb的简单路径的颜色段数量 ...

  6. 洛谷 - 试炼场(全部题目备份)

    整理的算法模板合集: ACM模板 目录 1.新手村 1 - 1 洛谷的第一个任务 1 - 2 顺序与分支 1 - 3 循环!循环!循环! 1 - 4 数组 1 - 5 简单字符串 1 - 6 过程函数 ...

  7. [洛谷 P4084 USACO17DEC] Barn Painting G (树形dp经典)

    [洛谷 P4084 USACO17DEC] Barn Painting G 题目链接 大致题意: 给定一颗N个节点组成的树,3种颜色,其中K个节点已染色,要求任意两相邻节点颜色不同,求合法染色方案数 ...

  8. 洛谷P4084 [USACO17DEC]Barn Painting G 题解

    洛谷P4084 [USACO17DEC]Barn Painting G 题解 题目链接:P4084 [USACO17DEC]Barn Painting G 题意:题意:给定一颗N个节点组成的树,3种颜 ...

  9. 洛谷:P6062 [USACO05JAN]Muddy Fields G

    题目链接:P6062 [USACO05JAN]Muddy Fields G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 此题重点在二分图的建图. 考虑放置木板的决策,由于可以重复 ...

最新文章

  1. apache和nginx的性能分析
  2. c++ gdi修改dpi_最新高血压标准修改,包括确诊标准和用药方案!你的药吃对了吗?...
  3. 修改Intellij IDEA中工程对应的Java SDK、Scala SDK
  4. C#获取键盘和鼠标操作的时间的类
  5. python查看对象占用内存_『Python』内存分析_List对象内存占用分析
  6. ethtool -g rx_魔兽怀旧服:黑G团避坑指南
  7. 传感器怎么获取障碍物的宽度信息_机器人感知 -- 测距传感器
  8. html的article标签,介绍一个html5做的网站,以及article标签的用法
  9. oracle bookauthor,Oracle 聚簇(征集)
  10. python 下采样和上采样
  11. How to research,22页PPT
  12. 机器学习:提升算法之Adaboost
  13. logistic模型预测人口python_基于python的logistic回归建模预测
  14. 物联网控制的智能LED灯带(1):WS2812灯带控制(WS2812/2811,ESP32,NODE-RED)
  15. 巨人综合音源优化版 – East West Quantum Leap Colossus Kontakt
  16. 使用多个路由器有线桥接实现无线漫游
  17. NOR Flash、NAND Flash和iNAND Flash的不同点
  18. 浅析Java的线程和Golang的协程
  19. html页面填充颜色,div填充颜色 怎么用css定义部分背景颜色
  20. 前后分离必备神器,YApi小白部署攻略

热门文章

  1. 2022LOL微博杯模糊问题,1080p高清看微博杯the shy比赛直播
  2. sscanf提取字符串数字
  3. 日记侠:你想开始写文章吗?(可以赚钱的)
  4. 读书印记 - 《文案创作完全手册:文案大师教你一步步写出销售力》
  5. Java模拟消息队列
  6. 学习云计算与大数据就业前景好吗?
  7. GPS 入门 1 —— 基础知识
  8. Ubuntu安装及常用软件安装
  9. Linux初探之如何查看帮助文档自学命令
  10. C语言火车票管理系统