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-染色 (树链剖分)的更多相关文章

  1. hysbz 2243 染色(树链剖分)

    题目链接:hysbz 2243 染色 题目大意:略. 解题思路:树链剖分+线段树的区间合并,可是区间合并比較简单,节点仅仅要记录左右端点的颜色就可以. #include <cstdio> ...

  2. HYSBZ - 2243 染色 (树链剖分+线段树)

    题意:树上每个结点有自己的颜色,支持两种操作:1.将u到v路径上的点颜色修改为c; 2.求u到v路径上有多少段不同的颜色. 分析:树剖之后用线段树维护区间颜色段数.区间查询区间修改.线段树结点中维护的 ...

  3. BZOJ 2243 染色 | 树链剖分模板题进阶版

    BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...

  4. HYSBZ 2243(树链剖分)

    题目连接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/D 题意:给定一棵有n个节点的无根树及点权和m个操作, ...

  5. BZOJ 2243 染色 树链剖分

    题意: 给出一棵树,每个顶点上有个颜色\(c_i\). 有两种操作: C a b c 将\(a \to b\)的路径所有顶点上的颜色变为c Q a b 查询\(a \to b\)的路径上的颜色段数,连 ...

  6. BZOJ - 2243 染色 (树链剖分+线段树+区间合并)

    题目链接 线段树维护区间连续段个数即可.设lc为区间左端点颜色,rc为区间右端点颜色,则合并两区间的时候,如果左区间右端点和右区间左端点颜色相同,则连续段个数-1. 在树链上的区间合并可以定义一个结构 ...

  7. BZOJ 2243: [SDOI2011]染色 [树链剖分]

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

  8. bzoj-2243 2243: [SDOI2011]染色(树链剖分)

    题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6267  Solved: 2291 Descript ...

  9. Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树

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

  10. BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

随机推荐

  1. MyEclipse 2014 + JSP+ Servlet

    来自:http://blog.csdn.net/21aspnet/article/details/21867241 1.安装准备 1).下载安装MyEclipse2014,这已经是最新版本. 2).下 ...

  2. 【Effective c++】条款6:若不想使用编译器自动生成的函数就应该明确拒绝

    地产中介卖的是房子,其使用的中介软件系统应该有个类用来描述卖掉的房子 class HomeFoeSale { ......} 但是任何房子都是独一无二的,不应该存在两个房子拥有同样的属性,因此以下操作 ...

  3. [Quick-x]cocos2dx下的彩色文本显示--RichLabel

    部分关键代码与思路参考 http://www.cocoachina.com/bbs/read.php?tid=218977&page=1 感谢原作者 i7909 代码下载地址:https:// ...

  4. Eclipse常见设置及快捷键使用总结(更新中)

    Eclipse中常见设置: 1.Eclipse在保存时设置自动去掉多余的import和格式化代码 路径: window --> preferences --> java --> Ed ...

  5. [Codeforces137B]Permutation(贪心?思路?,水题)

    题目链接:http://codeforces.com/contest/137/problem/B 给n个数字,要求修改成1~n的全排列数中的一个,修改的次数尽可能少,问最少需要修改几个数. 记下数组里 ...

  6. 替代Eval的两种方式

    在asp.net中的数据绑定中,我们经常会用到Eval,不过大家都知道Eval绑定是通过反射来实现的, 而反射势必会对性能造成一定的影响.不过有两种替代的方式来实现绑定数据,对性能略有提高. 1 当数 ...

  7. Kaleidoscope for mac

    mac下的对比工具Kaleidoscope,是一款不错的对比工具,界面被广大用户所喜爱. window下使用beyond compare 3,具体设置步骤,请见:http://www.cnblogs. ...

  8. Redis cluster学习 & Redis常识 & sort操作

    Redis中的5种数据类型String.Hash.List.Set.Sorted Set. Redis源码总代码一万多行. 这篇文章有一些Redis "常识" http://www ...

  9. iOS开发:视图生命周期

    iOS应用的视图状态分为以下几种 在viewcontroller的父类UIViewController中可以看到如下代码,通过重写不同的方法对操作视图渲染. @available(iOS 2.0, * ...

  10. UVa 10883 (组合数 对数) Supermean

    在纸上演算一下就能看出答案是:sum{ C(n-1, i) * a[i] / 2^(n-1) | 0 ≤ i ≤ n-1 } 组合数可以通过递推计算:C(n, k) = C(n, k-1) * (n- ...