[BZOJ 2243] [SDOI 2011] 染色 【树链剖分】
题目链接:BZOJ - 2243
题目分析
树链剖分...写了200+行...Debug了整整一天+...
静态读代码读了 5 遍 ,没发现错误,自己做小数据也过了。
提交之后全 WA 。
————————————— 杯具的分割线 —————————————————
然后看了别人代码。。然后发现。。
我写线段树区间修改竟然没打标记!!!!直接就修改上了!!!最裸的线段树都不会写了!!!
Warning!Warning!Warning!
代码
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm> using namespace std; const int MaxN = 100000 + 5; int n, m, Index;
int Father[MaxN], Son[MaxN], Depth[MaxN], Top[MaxN], A[MaxN], Size[MaxN], Pos[MaxN];
int Color[MaxN]; struct Edge
{
int v;
Edge *Next;
} E[MaxN * 2], *P = E, *Point[MaxN]; inline void AddEdge(int x, int y) {
++P; P -> v = y;
P -> Next = Point[x]; Point[x] = P;
} int DFS_1(int x, int Dep, int Fa) {
Depth[x] = Dep;
Father[x] = Fa;
Size[x] = 1;
int SonSize, MaxSonSize;
SonSize = MaxSonSize = 0;
for (Edge *j = Point[x]; j; j = j -> Next) {
if (j -> v == Fa) continue;
SonSize = DFS_1(j -> v, Dep + 1, x);
if (SonSize > MaxSonSize) {
Son[x] = j -> v;
MaxSonSize = SonSize;
}
Size[x] += SonSize;
}
return Size[x];
} void DFS_2(int x) {
if (x == 0) return;
if (x == Son[Father[x]]) Top[x] = Top[Father[x]];
else Top[x] = x;
Pos[x] = ++Index;
Color[Pos[x]] = A[x];
DFS_2(Son[x]);
for (Edge *j = Point[x]; j; j = j -> Next) {
if (j -> v == Father[x] || j -> v == Son[x]) continue;
DFS_2(j -> v);
}
} struct ES
{
int Lx, Rx, Tx;
ES() {}
ES(int a, int b, int c) {
Lx = a; Rx = b; Tx = c;
}
} T[MaxN * 4], D[MaxN * 4]; ES Plus(ES e1, ES e2) {
ES ret;
if (e1.Tx == 0) return e2;
if (e2.Tx == 0) return e1;
ret = ES(e1.Lx, e2.Rx, e1.Tx + e2.Tx);
if (e1.Rx == e2.Lx) --ret.Tx;
return ret;
} inline void Update(int x) {
T[x] = Plus(T[x << 1], T[x << 1 | 1]);
} void Plant_Tree(int x, int s, int t) {
if (s == t) {
T[x] = ES(Color[s], Color[s], 1);
D[x] = ES(0, 0, 0);
return;
}
int m = (s + t) >> 1;
Plant_Tree(x << 1, s, m);
Plant_Tree(x << 1 | 1, m + 1, t);
Update(x);
} inline void Paint(int x, ES Dlt) {
T[x] = Dlt;
D[x] = Dlt;
} inline void PushDown(int x) {
if (D[x].Tx == 0) return;
Paint(x << 1, D[x]);
Paint(x << 1 | 1, D[x]);
D[x] = ES(0, 0, 0);
} void Change_Tree(int x, int s, int t, int l, int r, int Col) {
if (l <= s && r >= t) {
ES Temp = ES(Col, Col, 1);
Paint(x, Temp);
return;
}
PushDown(x);
int m = (s + t) >> 1;
if (l <= m) Change_Tree(x << 1, s, m, l, r, Col);
if (r >= m + 1) Change_Tree(x << 1 | 1, m + 1, t, l, r, Col);
Update(x);
} void Change_Color(int x, int y, int z) {
int fx, fy;
while (true) {
fx = Top[x]; fy = Top[y];
if (Depth[fx] < Depth[fy]) {
swap(fx, fy);
swap(x, y);
}
if (fx == fy) {
if (Pos[x] < Pos[y]) Change_Tree(1, 1, n, Pos[x], Pos[y], z);
else Change_Tree(1, 1, n, Pos[y], Pos[x], z);
break;
}
else {
Change_Tree(1, 1, n, Pos[fx], Pos[x], z);
x = Father[fx];
}
}
} ES Query_Tree(int x, int s, int t, int l, int r) {
if (l <= s && r >= t) return T[x];
PushDown(x);
int m = (s + t) >> 1;
ES ret = ES(0, 0, 0);
if (l <= m) ret = Plus(ret, Query_Tree(x << 1, s, m, l, r));
if (r >= m + 1) ret = Plus(ret, Query_Tree(x << 1 | 1, m + 1, t, l, r));
return ret;
} int Query(int x, int y) {
int fx, fy, ret;
ES Ansx, Ansy, Temp;
Ansx = Ansy = ES(0, 0, 0);
while (true) {
fx = Top[x]; fy = Top[y];
if (Depth[fx] < Depth[fy]) {
swap(fx, fy);
swap(x, y);
swap(Ansx, Ansy);
}
if (fx == fy) {
ret = Ansx.Tx + Ansy.Tx;
if (Pos[x] < Pos[y]) {
Temp = Query_Tree(1, 1, n, Pos[x], Pos[y]);
ret += Temp.Tx;
if (Ansy.Lx == Temp.Rx) --ret;
if (Ansx.Lx == Temp.Lx) --ret;
}
else {
Temp = Query_Tree(1, 1, n, Pos[y], Pos[x]);
ret += Temp.Tx;
if (Ansx.Lx == Temp.Rx) --ret;
if (Ansy.Lx == Temp.Lx) --ret;
}
break;
}
else {
Ansx = Plus(Query_Tree(1, 1, n, Pos[fx], Pos[x]), Ansx);
x = Father[fx];
}
}
return ret;
} int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) scanf("%d", &A[i]);
int a, b, c;
for (int i = 1; i <= n - 1; ++i) {
scanf("%d%d", &a, &b);
AddEdge(a, b);
AddEdge(b, a);
}
DFS_1(1, 0, 0);
Index = 0;
DFS_2(1);
Plant_Tree(1, 1, n);
char ch;
int Ans;
for (int i = 1; i <= m; ++i) {
ch = '#';
while (ch != 'C' && ch != 'Q') ch = getchar();
if (ch == 'C') {
scanf("%d%d%d", &a, &b, &c);
Change_Color(a, b, c);
}
else {
scanf("%d%d", &a, &b);
Ans = Query(a, b);
printf("%d\n", Ans);
}
}
return 0;
}
[BZOJ 2243] [SDOI 2011] 染色 【树链剖分】的更多相关文章
- BZOJ 2243 SDOI 2011染色
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 算法讨论: 树链剖分把树放到线段树上.然后线段树的每个节点要维护的东西有左端点的颜色 ...
- BZOJ 2243 染色 | 树链剖分模板题进阶版
BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...
- BZOJ 2243: [SDOI2011]染色 [树链剖分]
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6651 Solved: 2432[Submit][Status ...
- Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5020 Solved: 1872[Submit][Status ...
- BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- BZOJ 2243: [SDOI2011]染色 树链剖分+线段树区间合并
2243: [SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数 ...
- BZOJ 2243: [SDOI2011]染色 (树链剖分+线段树合并)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 树链剖分的点剖分+线段树.漏了一个小地方,调了一下午...... 还是要细心啊! 结 ...
- [bzoj 2243]: [SDOI2011]染色 [树链剖分][线段树]
Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...
- BZOJ 2243 染色 树链剖分
题意: 给出一棵树,每个顶点上有个颜色\(c_i\). 有两种操作: C a b c 将\(a \to b\)的路径所有顶点上的颜色变为c Q a b 查询\(a \to b\)的路径上的颜色段数,连 ...
随机推荐
- 坚持c++,真正掌握c++(2)
在c++中对c中的输入输出进行了扩展,採用了面向对象的设计方法设计了c++中的输入输出(IO).输入输出依照操作的对象分类可分为:1. 标准IO(对计算机的键盘或者显示器进行读写操作).2. 文件IO ...
- [AngularJS] Sane, scalable Angular apps are tricky, but not impossible.
Read fromhttps://medium.com/@bluepnume/sane-scalable-angular-apps-are-tricky-but-not-impossible-less ...
- android 16 带返回值的activity
main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" andro ...
- ROS中Mangle解析
http://blog.csdn.net/bluecy/article/details/8192307
- linux下的僵尸进程处理SIGCHLD信号
什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打开的文件等,但内核为每一个终止子进程保存了一定量的信息.这些信息至少包括进程ID,进程的终止状态,以及该 ...
- IOS 播放动态Gif图片
图片分为静态和动态两种,图片的格式有很多种,在开发中比较常见的是.png和.jpg的静态图片,但有的时候在App中需要播放动态图片,比如.gif格式的小表情头像,在IOS中并没有提供直接显示动态图片的 ...
- switch-case参数类型
switch语句用法: 0. switch语句由一个控制表达式和多个case标签组成 1. switch控制表达式支持的类型有byte.short.char.int.enum(JDK5).String ...
- C++ 简单的入门语法
入门的hello world using namespace std; 是使用命名空间,有点像java里面的引入包main 方法和java一样是主入口,有且只有一个,因为是int ,所以还必须返回一个 ...
- C# 霍夫曼二叉树压缩算法实现
知道有的人比较懒,直接贴全部代码. 一开始一次性Code完了压缩部分代码.只调试了2,3次就成功了. 一次性写150行代码,没遇到什么bug的感觉还是蛮爽的. 写解压代码,才发现压缩代码有些细节问题. ...
- Android开发手记(30) 触摸及手势操作
触摸操作在现在智能手机系统中起到举足轻重的作用,本文将对安卓中的触摸以及一些简单手势的操作进行简单的介绍. 1.触摸 首先是关于触摸的判断,有两种方法可以判断的触摸操作. (1)setOnTouchL ...