[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\)的路径上的颜色段数,连 ...
随机推荐
- Handler具体解释系列(四)——利用Handler在主线程与子线程之间互发消息
MainActivity例如以下: package cc.c; import android.app.Activity; import android.os.Bundle; import androi ...
- I/O体系结构和设备驱动程序
http://blog.csdn.net/kafeiflynn/article/category/789844
- Java基础知识强化之集合框架笔记38:Set集合之Set集合概述和特点
1. Set集合概述和特点 Collection |--List 有序(存储顺序和取出顺序一致),可重复 |--Se ...
- Java基础知识强化09:String、StringBuffer和StringBuilder使用
1. 对于三者使用的总结: (1).如果要操作少量的数据用 = String (2).单线程操作字符串缓冲区下操作大量数据 = StringBuilder (3).多线程操 ...
- Linux 关闭及重启方式
一.shutdown 命令 作用:关闭或重启系统 使用权限:超级管理员使用 常用选项 1. -r 关机后立即重启 2. -h关机后不重启 3. -f快速关机,重启时跳过fsck(file system ...
- Linux试玩指令开机关机
Linux内核最初只是由芬兰人李纳斯·托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的. Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和U ...
- maven提示错误的解决办法
import或者new一个的maven project的时候,提示如下错误 Description Resource Path Location TypeCannot read ...
- java判断字符串是否为空的方法总结
http://blog.csdn.net/qq799499343/article/details/8492672 以下是java 判断字符串是否为空的四种方法: 方法一: 最多人使用的一个方法, 直观 ...
- java 进制.
/* 整数的'3'种表现形式: 1,十进制. 2,八进制. 3,十六进制. */ public class IntegerDemo { public static void main(String[] ...
- sql查看数据库表使用情况
如有更好的方式,希望交流. 感谢热心人,cc谢过 EXEC sys.sp_MSforeachtable @precommand = N'create table ##( 表名 sys ...