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. 比微软kinect更强的视频跟踪算法--TLD跟踪算法介绍

    转自:http://blog.csdn.net/carson2005/article/details/7647500 TLD(Tracking-Learning-Detection)是英国萨里大学的一 ...

  2. JodaTime初体验

    前段时间用JDK自带的Calendar类来处理日期,需要获取年.季,月,星期的起始日期,被折腾得要死要活.看了这篇文章 http://www.blogbus.com/dreamhead-logs/22 ...

  3. printf left justify

    http://www.lemoda.net/c/printf-left-justify/index.html This example program demonstrates how to left ...

  4. Mvc Kissy uploader实现图片批量上传 附带瀑布流的照片墙

    前言 KISSY 是由阿里集团前端工程师们发起创建的一个开源 JS 框架.它具备模块化.高扩展性.组件齐全,接口一致.自主开发.适合多种应用场景等特性.本人在一次项目中层使用这个uploader组件. ...

  5. NDK(17)让ndk支持完整C++,exception,rtti,

    C++ Support The Android platform provides a very minimal C++ runtime support library (/system/lib/li ...

  6. abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?

    abstract的method不可以是static的,因为抽象的方法是要被子类实现的,而static与子类扯不上关系! native方法表示该方法要用另外一种依赖平台的编程语言实现的,不存在着被子类实 ...

  7. bzoj3926

    题目的意思是叶子不超过20个……听说当初zjoi不少人被坑 分别对每个叶子以它为根dfs出20个dfs树,这样整个树的任何一个子串,都是某个dfs树上一个点到它的一个子孙的路径 每个dfs树,根到叶子 ...

  8. PHPnow 升级后 PHP不支持GD、MySQL

    来自http://tunps.com/php-unsupport-gd-and-mysql-after-upgrade-phpnow 最近磁盘格式化误操作后,最近两天都在忙于数据恢复,现在才恢复正常. ...

  9. 云计算服务模型,第 3 部分: 软件即服务(PaaS)

    英文原文:Cloud computing service models, Part 3: Software as a Service 软件即服务 (SaaS) 为商用软件提供基于网络的访问.您有可能已 ...

  10. C#网络资源列表

    1, http://club.topsage.com/thread-371996-1-1.html