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. Atheros AR9485 ubuntu 10.04 驱动安装及networking disable问题解决

    Laptop: ACER Aspire 5733-6629 Wireless:Lite-on HB125, CHIPS: Atheros AR9485 Ubuntu: 10.04LTS (2.6.32 ...

  2. C++STL之整理算法

    这里主要介绍颠倒.旋转.随机排列和分类4中常见的整理算法 1.颠倒(反转) void reverse(_BidIt _First, _BidIt _Last) _OutIt reverse_copy( ...

  3. LinuxShell算术运算

    Bash shell 的算术运算有四种方式:1:使用 expr 外部程式 加法 r=`expr 4 + 5`echo $r注意! '4' '+' '5' 这三者之间要有空白r=`expr 4 * 5` ...

  4. Akka的Actor模型及使用实例

    本文的绝大部分内容转载自rerun.me这一blog,老外写的东西就是好啊. ACTORS介绍 Anyone who has done multithreading in the past won't ...

  5. Qt之自定义界面(窗体缩放)

    简述 通过前两节内容,我们实现了自定义窗体的移动,以及自定义标题栏-用来显示窗体的图标.标题,以及控制窗体最小化.最大化.关闭. 在这之后,我们还缺少窗体的缩放-当鼠标移动到窗体的边框-左.上.右.下 ...

  6. JS调用客户端EXE

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. busybox filesystem add ldd function

    /******************************************************************** * busybox filesystem add ldd f ...

  8. mysql 索引与优化like查询

    索引与优化like查询 1. like %keyword    索引失效,使用全表扫描.但可以通过翻转函数+like前模糊查询+建立翻转函数索引=走翻转函数索引,不走全表扫描. 2. like key ...

  9. Java [Leetcode 190]Reverse Bits

    题目描述: everse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represente ...

  10. [转载]ios入门篇 -hello Word(1)

    温馨提示:,如果您使用移动终端阅读本篇文章,请连接wifi的情况下阅读,里面有大量图片,以免造成您不必要的损失.   潜水博客园很多年,闲来无事,聊一下自己的经历,语文不好(如有什么错别字,请您在下评 ...