HYSBZ 2243-染色 (树链剖分)
1A!!! 哈哈哈哈哈没看题解 没套模板哈哈哈哈 太感动了!!
如果只是线段树的话这道题倒是不难,只要记录左右边界就好了,类似很久以前做的hotel的题
但是树上相邻的段会有连续的
树上top[x]和fa[top[x]]是连续的,但是线段树上是算不到的,所以要判断下
线段树记录的是区间的数量,但是求单点的时候求得是颜色,需要注意下
#include <iostream>
#include <cstring>
#include <cstdio> using namespace std;
const int N = ;
int a[N]; struct Edge {
int to, next;
} edge[N*];
int head[N], cntE; void addedge(int u, int v) {
edge[cntE].to = v; edge[cntE].next = head[u]; head[u] = cntE++;
edge[cntE].to = u; edge[cntE].next = head[v]; head[v] = cntE++;
} int dep[N], fa[N], sz[N], son[N];
void dfs1(int u, int pre, int d) {
dep[u] = d;
sz[u] = ;
fa[u] = pre;
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (v != pre) {
dfs1(v, u, d+);
sz[u] += sz[v];
if (son[u] == - || sz[v] > sz[son[u]]) son[u] = v;
}
}
} int top[N], dfn[N], rk[N], idx;
void dfs2(int u, int tp) {
top[u] = tp;
dfn[u] = ++idx;
rk[idx] = u;
if (son[u] == -) return ;
dfs2(son[u], tp);
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (v != fa[u] && v != son[u]) {
dfs2(v, v);
}
}
} int tr[N<<], ltr[N<<], rtr[N<<]; // tr[i] means the number of color segment
int fg[N<<];
#define lson o<<1
#define rson o<<1|1 void pushup(int o) {
ltr[o] = ltr[lson];
rtr[o] = rtr[rson];
tr[o] = tr[lson] + tr[rson];
if (rtr[lson] == ltr[rson]) tr[o]--;
} void pushdown(int o) {
if (fg[o]) {
tr[lson] = tr[rson] = ;
fg[lson] = fg[rson] = fg[o];
ltr[lson] = ltr[rson] = ltr[o];
rtr[lson] = rtr[rson] = rtr[o];
fg[o] = ;
}
} void build(int o, int l, int r) {
fg[o] = ;
if (l == r) {
tr[o] = ;
ltr[o] = rtr[o] = a[rk[l]];
return;
}
int mid = (l+r) >> ;
build(lson, l, mid);
build(rson, mid+, r);
pushup(o);
} void change(int o, int l, int r, int L, int R, int v) {
if (l >= L && r <= R) {
fg[o] = ;
tr[o] = ;
ltr[o] = rtr[o] = v;
return ;
}
pushdown(o);
int mid = (l+r) >> ;
if (mid >= L) change(lson, l, mid, L, R, v);
if (mid < R) change(rson, mid+, r, L, R, v);
pushup(o);
} void CHANGE(int x, int y, int n, int c) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
change(, , n, dfn[top[x]], dfn[x], c);
x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
change(, , n, dfn[x], dfn[y], c);
} int query(int o, int l, int r, int L, int R) {
if (l >= L && r <= R) return tr[o];
pushdown(o);
int mid = (l+r) >> ;
if (mid < L) {
return query(rson, mid+, r, L, R);
} else if (mid >= R) {
return query(lson, l, mid, L, R);
} else {
int ans = query(lson, l, mid, L, R);
ans += query(rson, mid+, r, L, R);
if (ltr[rson] == rtr[lson]) ans--;
return ans;
}
} int qq(int o, int l, int r, int p) {
if (l == r) return ltr[o];
pushdown(o);
int mid = (l+r) >> ;
if (mid >= p) return qq(lson, l, mid, p);
return qq(rson, mid+, r, p);
} int QUERY(int x, int y, int n) {
int ans = ;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
ans += query(, , n, dfn[top[x]], dfn[x]);
if (qq(, , n, dfn[top[x]]) == qq(, , n, dfn[fa[top[x]]])) --ans;
x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
ans += query(, , n, dfn[x], dfn[y]);
return ans;
} void init() {
memset(head, -, sizeof head);
memset(son, -, sizeof son);
idx = cntE = ;
} int main()
{
//freopen("in.txt", "r", stdin);
int n, m;
while (~scanf("%d%d", &n, &m)) {
init();
for (int i = ; i <= n; ++i) scanf("%d", &a[i]);
int u, v, c;
for (int i = ; i < n; ++i) {
scanf("%d%d", &u, &v);
addedge(u, v);
}
dfs1(, , ); dfs2(, ); build(, , n); char op[];
while (m--) {
scanf("%s", op);
if (*op == 'Q') {
scanf("%d%d", &u, &v);
printf("%d\n", QUERY(u, v, n));
} else {
scanf("%d%d%d", &u, &v, &c);
CHANGE(u, v, n, c);
}
}
}
return ;
}
HYSBZ 2243-染色 (树链剖分)的更多相关文章
- hysbz 2243 染色(树链剖分)
题目链接:hysbz 2243 染色 题目大意:略. 解题思路:树链剖分+线段树的区间合并,可是区间合并比較简单,节点仅仅要记录左右端点的颜色就可以. #include <cstdio> ...
- HYSBZ - 2243 染色 (树链剖分+线段树)
题意:树上每个结点有自己的颜色,支持两种操作:1.将u到v路径上的点颜色修改为c; 2.求u到v路径上有多少段不同的颜色. 分析:树剖之后用线段树维护区间颜色段数.区间查询区间修改.线段树结点中维护的 ...
- BZOJ 2243 染色 | 树链剖分模板题进阶版
BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...
- HYSBZ 2243(树链剖分)
题目连接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/D 题意:给定一棵有n个节点的无根树及点权和m个操作, ...
- BZOJ 2243 染色 树链剖分
题意: 给出一棵树,每个顶点上有个颜色\(c_i\). 有两种操作: C a b c 将\(a \to b\)的路径所有顶点上的颜色变为c Q a b 查询\(a \to b\)的路径上的颜色段数,连 ...
- BZOJ - 2243 染色 (树链剖分+线段树+区间合并)
题目链接 线段树维护区间连续段个数即可.设lc为区间左端点颜色,rc为区间右端点颜色,则合并两区间的时候,如果左区间右端点和右区间左端点颜色相同,则连续段个数-1. 在树链上的区间合并可以定义一个结构 ...
- BZOJ 2243: [SDOI2011]染色 [树链剖分]
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6651 Solved: 2432[Submit][Status ...
- bzoj-2243 2243: [SDOI2011]染色(树链剖分)
题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6267 Solved: 2291 Descript ...
- 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 ...
随机推荐
- 前端自动化神器gulp使用记录
1.安装压缩图片插件的时候,由于网络原因,死活安装不成功.由于imagemin本身就包含很多插件,安装的时候卡住了,很是郁闷.如果要压缩png图片,那就单独安装imagemin-pngquant压缩插 ...
- .NET 框架 (转载)
转载:http://www.tracefact.net/CLR-and-Framework/DotNet-Framework.aspx .NET框架 三年前写的<.NET之美>的第六章,现 ...
- SQL延时操作
--使用waitfor语句延迟或暂停程序的执行 --waitfor{delay'time'|time 'time'} delay是指间隔时间 最长到24小时 time是指定时间执行 waitfor d ...
- 面试题_93_to_102_编程和代码相关的面试题
93)怎么检查一个字符串只包含数字?(解决方案) 94)Java 中如何利用泛型写一个 LRU 缓存?(答案<) 95)写一段 Java 程序将 byte 转换为 long?(答案) 95)在不 ...
- bzoj1063
仔细观察可以发现,这个规划路径很像树链剖分 树链剖分的经典定理:任意一个点到根的所经过轻边不超过logn 而这个规划路径所走公路相当于轻边,也就是说,不便利度不会很大 那么直接dp即可,设f[x,i, ...
- css3的背景多重运用
效果图: 简单代码: http://www.developerdrive.com/2013/08/introducing-css3-multiple-backgrounds/ 演示地址: http:/ ...
- HTMLayout界面CSSS样式解析笔记
HTMLayout学习笔记 by BBDXF 一.界面篇 学习界面需要有一定的HTML.CSS认知,如果你问为什么,那就当我白说. 由于界面库官方没有给一个完善的User guide,所有的学习都靠自 ...
- 脚本AI与脚本引擎
Scripted AI and Scripting Engines 脚本AI与脚本引擎 This chapter discusses some of the techniques you can us ...
- 【又见LCS】NYOJ-37 回文字符串
[题目链接] 回文字符串 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba& ...
- 【转】IOS NSTimer 定时器用法总结
原文网址:http://my.oschina.net/u/2340880/blog/398598 NSTimer在IOS开发中会经常用到,尤其是小型游戏,然而对于初学者时常会注意不到其中的内存释放问题 ...