BZOJ 2243: [SDOI2011]染色 树链剖分 区间合并
来源:互联网 发布:淘宝上哪家卖玉的店铺 编辑:程序博客网 时间:2024/05/19 06:19
题意:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。
思路:很明显需要一总数据结构来维护颜色
只是统计答案时 我门需要知道这段区间与下一段区间的联系 所以需要区间合并
对于不在重链上的点 我们看他与他的父亲颜色是否一样 加入一样贡献减1
对于lca位置不需要检查 直接统计答案
code:
#include<bits/stdc++.h>using namespace std;const int maxn = 1000010;int head[maxn], ecnt;struct EDGE{ int to, next;} edge[maxn << 1];void init(){ ecnt = 0; memset(head, -1, sizeof head);}void eadd(int u, int v){ edge[ecnt] = {v, head[u]}; head[u] = ecnt++;}int dad[maxn], sz[maxn], son[maxn], deep[maxn];void dfs_1(int u, int fa){ deep[u] = deep[fa] + 1, sz[u] = 1, dad[u] = fa; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v == fa) continue; dfs_1(v, u); sz[u] += sz[v]; if(!son[u] || sz[v] > sz[son[u]]) son[u] = v; }}int tid[maxn], top[maxn], tidclk ;void dfs_2(int u, int topu){ top[u] = topu, tid[u] = ++tidclk; if(!son[u]) return; dfs_2(son[u], topu); for(int i = head[u]; i!=-1; i = edge[i].next) { int v = edge[i].to; if(v == dad[u] || v == son[u]) continue; dfs_2(v, v); }}struct node{ int l, r; int ans, lc, rc, c;} tree[maxn << 2];void pushup(int root){ tree[root].lc = tree[root << 1].lc, tree[root].rc = tree[root << 1 | 1].rc; if(tree[root << 1].rc == tree[root << 1 | 1].lc) tree[root].ans = tree[root << 1].ans + tree[root << 1 | 1].ans - 1; else tree[root].ans = tree[root << 1].ans + tree[root << 1 | 1].ans;}void pushdown(int root){ if(tree[root].c) { tree[root << 1 | 1].ans = 1; tree[root << 1 | 1].lc = tree[root << 1 | 1].rc = tree[root << 1 | 1].c = tree[root].c; tree[root << 1].ans = 1; tree[root << 1].lc = tree[root << 1].rc = tree[root << 1].c = tree[root].c; tree[root].c = 0; }}void build(int root, int l, int r){ tree[root].l = l, tree[root].r = r; if(l == r) { tree[root].ans = tree[root].lc = tree[root].rc = tree[root].c = 0; } else { int mid = (l + r) >> 1; build(root << 1, l, mid); build(root << 1 | 1, mid + 1, r); pushup(root); }}void change(int root, int l, int r, int c){ if(l <= tree[root].l && tree[root].r <= r) { tree[root].ans = 1; tree[root].lc = tree[root].rc = tree[root].c = c; } else { pushdown(root); int mid = (tree[root].l + tree[root].r) >> 1; if(l <= mid) change(root << 1, l, r, c); if(mid < r) change(root << 1 | 1, l, r, c); pushup(root); }}int querry(int root, int l, int r){ if(l <= tree[root].l && tree[root].r <= r) { return tree[root].ans; } else { pushdown(root); int mid = (tree[root].l + tree[root].r) >> 1; int ans = 0; if(l <= mid) ans += querry(root << 1, l, r); if(r > mid) ans += querry(root << 1 | 1, l, r); if(l <= mid && r > mid && tree[root << 1].rc == tree[root << 1 | 1].lc) ans -= 1; return ans; }}int querryc(int root, int pos){ if(tree[root].l == tree[root].r) { return tree[root].lc; } pushdown(root); int mid = (tree[root].l + tree[root].r) >> 1; if(pos <= mid) return querryc(root << 1, pos); if(pos > mid ) return querryc(root << 1 | 1, pos);}int querry(int u, int v){ int ans = 0; while(top[u] != top[v]) { if(deep[top[u]] < deep[top[v]]) swap(u, v); ans += querry(1, tid[top[u]], tid[u]); if(querryc(1, tid[top[u]]) == querryc(1, tid[dad[top[u]]])) ans--; u = dad[top[u]]; } if(deep[u] > deep[v]) swap(u, v); ans += querry(1, tid[u], tid[v]); return ans;}void update(int u, int v, int c){ while(top[u] != top[v]) { if(deep[top[u]] < deep[top[v]]) swap(u, v); change(1, tid[top[u]], tid[u], c); u = dad[top[u]]; } if(deep[u] > deep[v]) swap(u, v); change(1, tid[u], tid[v], c);}int a[maxn];int main(){ init(); int n, m;scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i <= n - 1; i++) { int u, v; scanf("%d%d", &u, &v); eadd(u, v), eadd(v, u); } dfs_1(1, 0), dfs_2(1, 1); build(1, 1, n); for(int i = 1; i <= n; i++) change(1, tid[i], tid[i], a[i]); for(int i = 1; i <= m; i++) { char op[5]; scanf("%s", op + 1); if(op[1] == 'C') { int a, b, c; scanf("%d%d%d", &a, &b, &c); update(a, b, c); } else { int a, b; scanf("%d%d", &a, &b); printf("%d\n", querry(a, b)); } } return 0;}
阅读全文
0 0
- BZOJ 2243: [SDOI2011]染色 树链剖分 区间合并
- BZOJ 2243 [SDOI2011]染色 树链剖分+LCA+区间合并线段树
- bzoj 2243 [SDOI2011]染色 树链剖分区间更新
- 【bzoj2243】[SDOI2011]染色 树链剖分 (区间合并处理)
- 【BZOJ】2243 [SDOI2011]染色 树链剖分
- BZOJ 2243 SDOI2011 染色 树链剖分
- BZOJ 2243 [SDOI2011] 染色 (树链剖分)
- BZOJ 2243: [SDOI2011]染色 【树链剖分】
- BZOJ-2243: [SDOI2011]染色-树链剖分
- BZOJ 2243: [SDOI2011]染色 树链剖分
- BZOJ 2243: [SDOI2011]染色 树链剖分
- 【BZOJ】2243 [SDOI2011]染色 树链剖分
- bzoj 2243:[SDOI2011]染色 树链剖分
- 【BZOJ - 2243】 SDOI2011 染色
- BZOJ 2243: [SDOI2011]染色
- 【BZOJ 2243】 [SDOI2011]染色
- bzoj 2243: [SDOI2011]染色
- bzoj 2243: [SDOI2011]染色
- 发送手机验证码工具类
- HDU 6078 Wavel Sequence【动态规划】
- MFC+opencv遇到的问题汇总
- Android Studio导入第三方java类库含源代码包
- java集合之HashMap
- BZOJ 2243: [SDOI2011]染色 树链剖分 区间合并
- this和 $(this)的区别
- less-loader、css-loader、style-loader
- Unity3D利用Photon实现实时联网对战(一)Photon Sever介绍
- 密码加密
- vue单页面兄弟组件信息传递
- Android动态布局
- Hash算法解决冲突的方法一般有以下几种常用的解决方法
- c语言中printf("%x",-1);为什么会输出-1的十六进制补码??