BZOJ 3306|树|树链剖分
2016-02-14 18:46
363 查看
和bzoj 3083比就是弱化版了。
样例都有点像?
http://blog.csdn.net/huanghongxun/article/details/50663457
Submit: 608 Solved: 192
* 换根
* 修改点权
* 查询子树最小值
接下来n行,每行两个整数f,v,第i+1行的两个数表示点i的父亲和点i的权。保证f < i。如 果f = 0,那么i为根。输入数据保证只有i = 1时,f = 0。
接下来 m 行,为以下格式中的一种:
• V x y表示把点x的权改为y
• E x 表示把有根树的根改为点 x
• Q x 表示查询点 x 的子树最小值
0 1
1 2
1 3
Q 1
V 1 6
Q 1
V 2 5
Q 1
V 3 4
Q 1
2
3
4
样例都有点像?
http://blog.csdn.net/huanghongxun/article/details/50663457
#include <cstdio> #include <algorithm> using namespace std; const int N = 100005, M = N * 3, inf = 0x7fffffff; int read() { int s = 0, f = 1; char ch = getchar(); for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = -1; for (; '0' <= ch && ch <= '9'; ch = getchar()) s = s * 10 + ch - '0'; return s * f; } int next[M], to[M], head , sz , son , top , c , f , fa , dep , pos , cnt = 0; int end , num[M], lazy[M], rt = 1, n, tot = 0; void add(int u, int v) { next[++cnt] = head[u]; head[u] = cnt; to[cnt] = v; next[++cnt] = head[v]; head[v] = cnt; to[cnt] = u; } void dfs1(int x) { sz[x] = 1; son[x] = 0; for (int i = head[x]; i; i = next[i]) if (to[i] != fa[x]) { fa[to[i]] = x; dep[to[i]] = dep[x] + 1; dfs1(to[i]); if (sz[to[i]] > sz[son[x]]) son[x] = to[i]; sz[x] += sz[to[i]]; } } void dfs2(int x, int t) { pos[x] = ++tot; top[x] = t; if (son[x] != 0) dfs2(son[x], t); for (int i = head[x]; i; i = next[i]) if (to[i] != son[x] && to[i] != fa[x]) dfs2(to[i], to[i]); end[x] = tot; } void pushdown(int t) { if (lazy[t]) { num[t * 2 + 1] = lazy[t * 2 + 1] = num[t * 2] = lazy[t * 2] = lazy[t]; lazy[t] = 0; } } void modify(int t, int l, int r, int ql, int qr, int z) { int mid = l + r >> 1; if (l == ql && r == qr) { num[t] = lazy[t] = z; return; } pushdown(t); if (qr <= mid) modify(t * 2, l, mid, ql, qr, z); else if (mid < ql) modify(t * 2 + 1, mid + 1, r, ql, qr, z); else modify(t * 2, l, mid, ql, mid, z), modify(t * 2 + 1, mid + 1, r, mid + 1, qr, z); num[t] = min(num[t * 2], num[t * 2 + 1]); } void modify(int x, int y, int z) { int fx = top[x], fy = top[y]; while (fx != fy) { if (dep[fx] < dep[fy]) swap(fx, fy), swap(x, y); modify(1, 1, n, pos[fx], pos[x], z); x = fa[fx], fx = top[x]; } if (dep[x] > dep[y]) swap(x, y); modify(1, 1, n, pos[x], pos[y], z); } int query(int t, int l, int r, int ql, int qr) { int mid = l + r >> 1; if (l == ql && r == qr) return num[t]; pushdown(t); if (qr <= mid) return query(t * 2, l, mid, ql, qr); else if (mid < ql) return query(t * 2 + 1, mid + 1, r, ql, qr); else return min(query(t * 2, l, mid, ql, mid), query(t * 2 + 1, mid + 1, r, mid + 1, qr)); } int query(int x) { if (x == rt) return query(1, 1, n, 1, n); if (pos[rt] < pos[x] || pos[rt] > end[x]) return query(1, 1, n, pos[x], end[x]); int i, ans = inf; for (i = head[x]; i; i = next[i]) if (pos[rt] >= pos[to[i]] && pos[rt] <= end[to[i]] && to[i] != fa[x]) { if (pos[to[i]] > 1) ans = min(ans, query(1, 1, n, 1, pos[to[i]] - 1)); if (end[to[i]] < n) ans = min(ans, query(1, 1, n, end[to[i]] + 1, n)); break; } return ans; } void build(int t, int l, int r) { int mid = l + r >> 1; if (l == r) { num[t] = c[l]; return; } build(t * 2, l, mid); build(t * 2 + 1, mid + 1, r); num[t] = min(num[t * 2], num[t * 2 + 1]); } int main() { char op[2]; int i, j, m; n = read(); m = read(); for (i = 1; i <= n; i++) add(i, read()), f[i] = read(); dfs1(rt); dfs2(rt, rt); for (i = 1; i <= n; i++) c[pos[i]] = f[i]; build(1, 1, n); while (m--) { scanf("%s", op); switch(op[0]) { case 'E': rt = read(); break; case 'V': i = read(); j = read(); modify(i, i, j); break; case 'Q': printf("%d\n", query(read())); break; } } return 0; }
3306: 树
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 608 Solved: 192
Description
给定一棵大小为 n 的有根点权树,支持以下操作:* 换根
* 修改点权
* 查询子树最小值
Input
第一行两个整数 n, Q ,分别表示树的大小和操作数。接下来n行,每行两个整数f,v,第i+1行的两个数表示点i的父亲和点i的权。保证f < i。如 果f = 0,那么i为根。输入数据保证只有i = 1时,f = 0。
接下来 m 行,为以下格式中的一种:
• V x y表示把点x的权改为y
• E x 表示把有根树的根改为点 x
• Q x 表示查询点 x 的子树最小值
Output
对于每个 Q ,输出子树最小值。Sample Input
3 70 1
1 2
1 3
Q 1
V 1 6
Q 1
V 2 5
Q 1
V 3 4
Q 1
Sample Output
12
3
4
HINT
对于 100% 的数据:n, Q ≤ 10^5。相关文章推荐
- Git教程
- 24. Swap Nodes in Pairs LeetCode
- CMAKE自动构建
- 第31讲:Option使用和实现内幕源码揭秘
- K-近邻分类算法(监督式)
- USACO Milking Cows 解题日志
- 46. Permutations LeetCode
- loganalyzer部署文档(第二部分)
- woj1034 hdu1290 Cut the Apple 数学题
- javascript中的with关键字
- 121. Best Time to Buy and Sell Stock LeetCode
- Linux deepin 15.1配置java环境
- redis 安装配置和jedis操作
- 回文数与回文字符串的判断
- 递归太深会导致栈溢出
- 从graphite中删除字段信息
- spring和Hibernate 整合
- Swagger 与 SpringMVC 整合的步骤
- 62. Unique Paths LeetCode
- Linux 下的自解压工具