[BZOJ4817][SDOI2017]树点涂色(DFS序+LCA+树剖+LCT)
来源:互联网 发布:淘宝店铺运动服简介 编辑:程序博客网 时间:2024/05/17 02:13
我一眼以为是裸树剖,但是看完问题就知道不是那么容易了。因为只用树剖不能很好地维护操作
首先,按照原树,构建出一个全部都是虚边的
我们发现,操作
这样,询问
代码:
#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define p2 p << 1#define p3 p << 1 | 1using namespace std;inline int read() { int res = 0; bool bo = 0; char c; while (((c = getchar()) < '0' || c > '9') && c != '-'); if (c == '-') bo = 1; else res = c - 48; while ((c = getchar()) >= '0' && c <= '9') res = (res << 3) + (res << 1) + (c - 48); return bo ? ~res + 1 : res;}const int N = 1e5 + 5, LogN = 24;int n, m, ecnt, nxt[N << 1], adj[N], go[N << 1], fa_s[N], lc[N], rc[N],QAQ, fa[N][LogN], dep[N], sze[N], son[N], top[N], pos[N], idx[N], T[N << 2],add[N << 2], ml[N];void add_edge(int u, int v) { nxt[++ecnt] = adj[u]; adj[u] = ecnt; go[ecnt] = v;}int which(int x) {return rc[fa_s[x]] == x;}bool is_root(int x) { return !fa_s[x] || (lc[fa_s[x]] != x && rc[fa_s[x]] != x);}void upd(int x) { ml[x] = lc[x] ? ml[lc[x]] : x;}void rotate(int x) { int y = fa_s[x], z = fa_s[y], b = lc[y] == x ? rc[x] : lc[x]; if (z && !is_root(y)) (lc[z] == y ? lc[z] : rc[z]) = x; fa_s[x] = z; fa_s[y] = x; if (b) fa_s[b] = y; if (lc[y] == x) rc[x] = y, lc[y] = b; else lc[x] = y, rc[y] = b; upd(y); upd(x);}void splay(int x) { while (!is_root(x)) { if (!is_root(fa_s[x])) { if (which(x) == which(fa_s[x])) rotate(fa_s[x]); else rotate(x); } rotate(x); } upd(x);}void dfs1(int u, int fu) { int i; fa[u][0] = fu; dep[u] = dep[fu] + 1; sze[u] = 1; for (i = 0; i <= 19; i++) fa[u][i + 1] = fa[fa[u][i]][i]; for (int e = adj[u], v; e; e = nxt[e]) { if ((v = go[e]) == fu) continue; dfs1(v, u); sze[u] += sze[v]; if (sze[v] > sze[son[u]]) son[u] = v; }}void dfs2(int u, int fu) { if (son[u]) { top[son[u]] = top[u]; idx[pos[son[u]] = ++QAQ] = son[u]; dfs2(son[u], u); } for (int e = adj[u], v; e; e = nxt[e]) { if ((v = go[e]) == fu || v == son[u]) continue; top[v] = v; idx[pos[v] = ++QAQ] = v; dfs2(v, u); }}void build(int l, int r, int p) { if (l == r) return (void) (T[p] = dep[idx[l]]); int mid = l + r >> 1; build(l, mid, p2); build(mid + 1, r, p3); T[p] = max(T[p2], T[p3]);}void down(int p) { add[p2] += add[p]; add[p3] += add[p]; add[p] = 0;}void upt(int p) { T[p] = max(T[p2] + add[p2], T[p3] + add[p3]);}void change(int l, int r, int s, int e, int v, int p) { if (l == s && r == e) return (void) (add[p] += v); int mid = l + r >> 1; down(p); if (e <= mid) change(l, mid, s, e, v, p2); else if (s >= mid + 1) change(mid + 1, r, s, e, v, p3); else change(l, mid, s, mid, v, p2), change(mid + 1, r, mid + 1, e, v, p3); upt(p);}int query(int l, int r, int s, int e, int p) { if (l == s && r == e) return T[p] + add[p]; int mid = l + r >> 1, res = 0; down(p); if (e <= mid) res = query(l, mid, s, e, p2); else if (s >= mid + 1) res = query(mid + 1, r, s, e, p3); else res = max(query(l, mid, s, mid, p2), query(mid + 1, r, mid + 1, e, p3)); upt(p); return res;}void init() { int i; QAQ = top[1] = pos[1] = idx[1] = 1; dfs1(1, 0); dfs2(1, 0); build(1, n, 1); for (i = 1; i <= n; i++) fa_s[i] = fa[i][0], ml[i] = i;}void Access(int x) { int y; for (y = 0; x; y = x, x = fa_s[x]) { splay(x); if (rc[x]) change(1, n, pos[ml[rc[x]]], pos[ml[rc[x]]] + sze[ml[rc[x]]]- 1, 1, 1); if (y) change(1, n, pos[ml[y]], pos[ml[y]] + sze[ml[y]] - 1, -1, 1); rc[x] = y; if (y) fa_s[y] = x; }}int lca(int u, int v) { int i; if (dep[u] < dep[v]) swap(u, v); for (i = 20; i >= 0; i--) { if (dep[fa[u][i]] >= dep[v]) u = fa[u][i]; if (u == v) return u; } for (i = 20; i >= 0; i--) if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i]; return fa[u][0];}int path_query(int u, int v) { int w = lca(u, v), res; res = query(1, n, pos[u], pos[u], 1) + query(1, n, pos[v], pos[v], 1); return res - (query(1, n, pos[w], pos[w], 1) << 1) + 1;}int main() { int i, op, x, y; n = read(); m = read(); for (i = 1; i < n; i++) { x = read(); y = read(); add_edge(x, y); add_edge(y, x); } init(); while (m--) { op = read(); x = read(); if (op == 1) Access(x); else if (op == 2) y = read(), printf("%d\n", path_query(x, y)); else printf("%d\n", query(1, n, pos[x], pos[x] + sze[x] - 1, 1)); } return 0;}
阅读全文
0 0
- [BZOJ4817][SDOI2017]树点涂色(DFS序+LCA+树剖+LCT)
- [LCT] BZOJ4817.[Sdoi2017]树点涂色
- BZOJ4817 [Sdoi2017]树点涂色
- BZOJ4817: [Sdoi2017]树点涂色
- bzoj4817 [Sdoi2017]树点涂色
- 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序
- loj #2001. 「SDOI2017」树点涂色(LCT)
- [LCT] BZOJ 4817 [Sdoi2017]树点涂色
- [SDOI2017]树点涂色
- [SDOI2017]树点涂色
- 4817: [Sdoi2017]树点涂色
- bzoj 4817: [Sdoi2017]树点涂色
- BZOJ4817 SDOI2017 相关分析
- bzoj 4817: [Sdoi2017]树点涂色 link cut tree+线段树+树链剖分
- [NOIP2016] 天天爱跑步 (LCA+线段树(动态开点)+差分+dfs序)
- bzoj3779 lct+线段树+dfs序
- [BZOJ4539][Hnoi2016]树(dfs序+主席树+lca)
- [BZOJ3589]动态树(树链剖分+dfs序+lca)
- Spark学习之二-Spark入门
- 利用maven搭建一个简单的hibernate示例
- java后台分层
- Android应用自动更新、下载、安装
- Python中的实例方法,类方法, 静态方法
- [BZOJ4817][SDOI2017]树点涂色(DFS序+LCA+树剖+LCT)
- ajax向controller发送请求 页面不跳转到另一个页面
- Lucene之超链接传中文乱码
- Spark学习之三-RDD编程
- android 8.0 开发
- ALV设置参考表和参考字段,自定义列名称可能失效
- eayUI datagrid 列合并、合并列
- LeetCode Convert BST to Greater Tree
- 541. Reverse String II