[点分树] BZOJ 4372: 烁烁的游戏
来源:互联网 发布:彩虹6号 淘宝 编辑:程序博客网 时间:2024/06/08 05:49
Description
给一颗
Solution
点分树大裸题。
先把点分树建出来,记录下分治结构上的祖先以及到该祖先的距离。
对每个点以深度为关键字建线段树,维护所管辖的分支结构的信息。
那么修改只要往分治树上爬,在线段树修改就好了。
当然要减掉从当前点走到分治树祖先又走回来的东西。
开两颗线段树就好了。
查询的话直接暴力爬分治树就好啦。
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int INF = 1 << 30;const int B = 100;const int N = 101010;const int M = 30;inline char get(void) { static char buf[100000], *S = buf, *T = buf; if (S == T) { T = (S = buf) + fread(buf, 1, 100000, stdin); if (S == T) return EOF; } return *S++;}template<typename T>inline void read(T &x) { static char c; x = 0; int sgn = 0; for (c = get(); c < '0' || c > '9'; c = get()) if (c == '-') sgn = 1; for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0'; if (sgn) x = -x;}inline void reado(int &opt) { static char c; for (c = get(); c != 'M' && c != 'Q'; c = get()); opt = (c == 'M');}int n, m, x, y, z, Gcnt, Tcnt, opt;struct edge { int to, next; edge (int t = 0, int n = 0):to(t), next(n) {}};edge G[N << 1];int head[N];int fa[N][M], dis[N][M];int size[N], vis[N], mxd[N];int root, mn, rt, sum, cnt;int rt1[N], rt2[N], ls[N * B], rs[N * B], t[N * B];inline void AddEdge(int from, int to) { G[++Gcnt] = edge(to, head[from]); head[from] = Gcnt; G[++Gcnt] = edge(from, head[to]); head[to] = Gcnt;}inline void Add(int &o, int l, int r, int L, int R, int x) { if (!o) o = ++Tcnt; if (l >= L && r <= R) return (void)(t[o] += x); int mid = (l + r) >> 1; if (L <= mid) Add(ls[o], l, mid, L, R, x); if (R > mid) Add(rs[o], mid + 1, r, L, R, x);}inline int Sum(int o, int l, int r, int pos) { if (l == r || !o) return t[o]; int mid = (l + r) >> 1; if (pos <= mid) return t[o] + Sum(ls[o], l, mid, pos); else return t[o] + Sum(rs[o], mid + 1, r, pos);}inline void GetRoot(int u, int f) { int to, h = 0; size[u] = 1; for (int i = head[u]; i; i = G[i].next) { to = G[i].to; if (vis[to] || to == f) continue; GetRoot(to, u); size[u] += size[to]; h = max(size[to], h); } h = max(sum - size[u], h); if (h < mn) { root = u; mn = h; }}inline void dfs(int u, int f, int d) { int to; ++cnt; mxd[rt] = max(mxd[rt], d); fa[u][++*fa[u]] = rt; dis[u][++*dis[u]] = d; for (int i = head[u]; i; i = G[i].next) { to = G[i].to; if (to == f || vis[to]) continue; dfs(to, u, d + 1); }}inline void DivAndConq(int u) { vis[u] = 1; int to; rt = u; mxd[rt] = 0; fa[u][++*fa[u]] = rt; dis[u][++*dis[u]] = 0; for (int i = head[u]; i; i = G[i].next) { to = G[i].to; if (vis[to]) continue; cnt = 0; dfs(to, u, 1); size[to] = cnt; } for (int i = head[u]; i; i = G[i].next) { to = G[i].to; if (vis[to]) continue; mn = INF; sum = size[to]; GetRoot(to, u); DivAndConq(root); }}inline void Modify(int v, int k, int x) { int u = v, kk, fu; Add(rt1[u], 0, mxd[u], 0, min(k, mxd[u]), x); for (int i = 2; i <= *fa[v]; i++) { fu = fa[v][i]; kk = k - dis[v][i]; if (kk < 0) { u = fu; continue; } Add(rt2[u], 0, mxd[fu], 0, min(kk, mxd[fu]), -x); u = fu; Add(rt1[u], 0, mxd[u], 0, min(kk, mxd[u]), x); }}inline int Query(int v) { int ans = 0, u = v, fu; ans += Sum(rt1[u], 0, mxd[u], 0); for (int i = 2; i <= *fa[v]; i++) { fu = fa[v][i]; ans += Sum(rt2[u], 0, mxd[fu], dis[v][i]); u = fu; ans += Sum(rt1[u], 0, mxd[u], dis[v][i]); } return ans;}inline void Debug(void) { for (int i = 1; i <= n; i++) printf("w(%d)%d%c", i, Query(i), i == n ? '\n' : ' ');}int main(void) { freopen("1.in", "r", stdin); read(n); read(m); for (int i = 1; i < n; i++) { read(x); read(y); AddEdge(x, y); } mn = INF; sum = n; GetRoot(1, 0); DivAndConq(root); for (int i = 1; i <= n; i++) { reverse(fa[i] + 1, fa[i] + *fa[i] + 1); reverse(dis[i] + 1, dis[i] + *dis[i] + 1); } while (m--) { reado(opt); read(x); if (opt) { read(y); read(z); Modify(x, y, z); } else { printf("%d\n", Query(x)); } } return 0;}
阅读全文
2 0
- [点分树] BZOJ 4372: 烁烁的游戏
- bzoj 4372: 烁烁的游戏 (动态点分治+线段树+LCA)
- 【bzoj4372】 烁烁的游戏
- 【BZOJ4372】烁烁的游戏 动态树分治
- [BZOJ4372][动态树分治(点分树)][动态开点线段树]烁烁的游戏
- [BZOJ4372][烁烁的游戏][动态树分治+线段树+LCA]
- BZOJ 3729 Gty的游戏
- BZOJ 3729: Gty的游戏
- BZOJ 4169: Lmc的游戏
- 游戏 BZOJ
- [Splay] BZOJ 3729 Gty的游戏
- BZOJ 1199: [HNOI2005]汤姆的游戏
- BZOJ 2756 [SCOI2012]奇怪的游戏
- BZOJ 2756 [SCOI2012]奇怪的游戏
- [BZOJ]1022 小约翰的游戏
- BZOJ 1444 [Jsoi2009] 有趣的游戏
- BZOJ P2756[SCOI2012]奇怪的游戏
- bzoj 1444 [Jsoi2009]有趣的游戏
- Linux系统管理用户
- HDOJ 1020 Encoding
- DOM访问列表框、下拉菜单的常用属性
- 第二次导师培训课
- JavaScript实现随机显示小星星
- [点分树] BZOJ 4372: 烁烁的游戏
- AR之路--artoolkit5让第一个例子运行起来
- 点灯小游戏 平台:VS2015 需要安装图形库EasyX(600K左右)基于C++语言的win32控制台应用程序
- 用Python实现电子邮件接收程序(POP3)
- HDOJ 1022 Train Problem I (堆栈的应用)
- 白帽黑客TK:黑客都是一群什么人?
- 测试报告参考规范之测试工具、风险和应急
- [机器学习:李宏毅]27、Ensemble
- dedecms织梦后台模板layui框架-20171126更新