hdu 4897 Little Devil I(树链剖分+线段树)
来源:互联网 发布:js 精确计时 编辑:程序博客网 时间:2024/04/29 22:48
题目链接:hdu 4897 Little Devil I
题目大意:给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作:
- 1 u v:u到v路径上的边都取成相反的颜色
- 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一个节点在路径上)
- 3 u v:查询u到v路径上有多少个黑色边
解题思路:树链剖分,用两个线段W和L维护,W对应的是每条的黑白情况,L表示的是每个节点的相邻边翻转情况
(对于轻链而言,重链直接在W上修改)
对于1操作,即为普通的树链剖分,直接在W上修改即可。
对于2操作,每次修改在L上,不过链的两端(即重链的部分)还需要在W上修改
对于3操作,每次查询,重链可以直接根据W中的值判断,轻链还要根据对应节点的L值来确定。
#pragma comment(linker, "/STACK:1024000000,1024000000")#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 1e5+5;#define lson(x) ((x)<<1)#define rson(x) (((x)<<1)|1)struct Tree { int lc[maxn << 2], rc[maxn << 2], fp[maxn << 2], s[maxn << 2]; void splay(int u) { s[u] = rc[u] - lc[u] + 1 - s[u]; fp[u] ^= 1; } void pushup(int u) { s[u] = s[lson(u)] + s[rson(u)]; } void pushdown(int u) { if (fp[u]) { splay(lson(u)); splay(rson(u)); fp[u] = 0; } } void build (int u, int l, int r) { lc[u] = l; rc[u] = r; fp[u] = s[u] = 0; if (l == r) return; int mid = (l + r) / 2; build(lson(u), l, mid); build(rson(u), mid + 1, r); pushup(u); } void modify(int u, int l, int r) { if (l <= lc[u] && rc[u] <= r) { splay(u); return; } pushdown(u); int mid = (lc[u] + rc[u]) / 2; if (l <= mid) modify(lson(u), l, r); if (r > mid) modify(rson(u), l, r); pushup(u); } int query(int u, int l, int r) { if (l <= lc[u] && rc[u] <= r) return s[u]; pushdown(u); int mid = (lc[u] + rc[u]) / 2, ret = 0; if (l <= mid) ret += query(lson(u), l, r); if (r > mid) ret += query(rson(u), l, r); pushup(u); return ret; }}W, L;int N, Q, E, first[maxn], jump[maxn * 2], link[maxn * 2];int id, idx[maxn], top[maxn], far[maxn], son[maxn], dep[maxn], cnt[maxn];inline void add_Edge(int u, int v) { link[E] = v; jump[E] = first[u]; first[u] = E++;}void dfs (int u, int pre, int d) { far[u] = pre; son[u] = 0; cnt[u] = 1; dep[u] = d; for (int i = first[u]; i + 1; i = jump[i]) { int v = link[i]; if (v == pre) continue; dfs(v, u, d + 1); cnt[u] += cnt[v]; if (cnt[son[u]] < cnt[v]) son[u] = v; }}void dfs (int u, int rot) { top[u] = rot; idx[u] = ++id; if (son[u]) dfs(son[u], rot); for (int i = first[u]; i + 1; i = jump[i]) { int v = link[i]; if (v == far[u] || v == son[u]) continue; dfs(v, v); }}void init () { E = id = 0; memset(first, -1, sizeof(first)); int u, v; scanf("%d", &N); for (int i = 1; i < N; i++) { scanf("%d%d", &u, &v); add_Edge(u, v); add_Edge(v, u); } dfs(1, 0, 0); dfs(1, 1); W.build(1, 1, N); L.build(1, 1, N);}void modify(int u, int v, int k) { int p = top[u], q = top[v]; while (p != q) { if (dep[p] < dep[q]) { swap(p, q); swap(u, v); } if (k) { L.modify(1, idx[p], idx[u]); W.modify(1, idx[p], idx[p]); W.modify(1, idx[son[u]], idx[son[u]]); } else W.modify(1, idx[p], idx[u]); u = far[p]; p = top[u]; } if (dep[u] > dep[v]) swap(u, v); if (k) { L.modify(1, idx[u], idx[v]); W.modify(1, idx[u], idx[u]); W.modify(1, idx[son[v]], idx[son[v]]); } else { if (u == v) return; W.modify(1, idx[son[u]], idx[v]); }}int query(int u, int v) { int p = top[u], q = top[v], ret = 0; while (p != q) { if (dep[p] < dep[q]) { swap(p, q); swap(u, v); } if (u != p) ret += W.query(1, idx[son[p]], idx[u]); ret += (W.query(1, idx[p], idx[p]) ^ L.query(1, idx[far[p]], idx[far[p]])); u = far[p]; p = top[u]; } if (u == v) return ret; if (dep[u] > dep[v]) swap(u, v); ret += W.query(1, idx[son[u]], idx[v]); return ret;}int main () { int cas; scanf("%d", &cas); while (cas--) { init(); int k, u, v; scanf("%d", &Q); while (Q--) { scanf("%d%d%d", &k, &u, &v); if (k == 3) printf("%d\n", query(u, v)); else modify(u, v, k - 1); } } return 0;}
3 0
- hdu 4897 Little Devil I(树链剖分+线段树)
- 【BZOJ3862】Little Devil I【树链剖分】【线段树】
- hdu4897 Little Devil I(树链剖分+线段树)
- hdu 4897 Little Devil I 树链剖分
- 【hdu 4897】Little Devil I
- hdu 4897 Little Devil I
- bzoj 3862: Little Devil I (树链剖分+线段树)
- 【HDU】4987 Little Devil I 树链剖分
- 【HDU 4897 多校联合】Little Devil I【树链刨分】
- hdu 4897 Little Devil I 树剖(题如其名..)
- bzoj3862Little Devil I(树链剖分+线段树)
- bzoj3862: Little Devil I
- hdu_4897_Little Devil I(树链剖分)
- hdu I Hate I t线段树
- 【HDU 4905 多校联合】The Little Devil II【DP+四边形不等式优化】
- hdu 4905 The Little Devil II 区间DP 四边形不等式优化
- hdu 4905 The Little Devil II 多校第四场 DP
- I hate it HDU【线段树】
- QML元素
- 数据结构与算法(个人总结)
- hdoj 2203 亲和串
- meachine learning
- Sqoop1.99.3安装(Hadoop 2.4.1版本)
- hdu 4897 Little Devil I(树链剖分+线段树)
- linux grep命令
- Android知识笔记
- 刚做完的一个MATLAB GUI
- Mybatis中oracle、mysql、db2、sql server的like模糊查询
- android 学习笔记1——环境搭建
- 斐波那契博弈证明
- javascript函数
- Olingo client的使用