【NOI 2015 软件包管理器】【树剖】
来源:互联网 发布:矩阵的乘法计算方法 编辑:程序博客网 时间:2024/06/08 15:27
Luogu P2146 软件包管理器
思想有点妙 …
- 每次安装软件,就把根节点到 x 软件路径上的值全部变为 1
- 同理,每次卸载软件,就把 x 以及它的子树的值变为 0
故我们可以用区间和的思想,每次操作之前记录一下 tr[root].sum
的值,更新之后再查询一遍 tr[root].sum
的值,两者之差的绝对值则为答案。
然后注意一下细节,比如 lazy
更新完以后要么是 0
要么是 1
,所以判断的时候和普通不一样;还有因为实际根节点是从 0
开始的,线段树我的根节点是从 1
开始的,所以要注意每次调用要想清楚到底调用的是实际的还是线段树的。
#include <bits/stdc++.h>#define ll long longusing namespace std;const int N = 1e5 + 5;int n;int a[N], head[N];struct Edge { int to, next;}e[N << 1];int cnt = 0;void add(int u, int v) { e[++ cnt].to = v; e[cnt].next = head[u]; head[u] = cnt;}//---------int fa[N], dep[N], son[N], size[N];void dfs1(int u, int f, int depth) { fa[u] = f; dep[u] = depth; size[u] = 1; for (int i = head[u]; i; i = e[i].next) { int v = e[i].to; if (v != f) { dfs1(v, u, depth + 1); size[u] += size[v]; if (son[u] == -1 || size[son[u]] < size[v]) son[u] = v; } }} int tim = 0;int top[N], tid[N], Rank[N];void dfs2(int u, int tp) { top[u] = tp; tid[u] = ++ tim; Rank[tim] = u; if (son[u] == -1) return ; dfs2(son[u], tp); for (int i = head[u]; i; i = e[i].next) { int v = e[i].to; if (v != fa[u] && v != son[u]) dfs2(v, v); }}//----------struct Node { int sum, lazy; }tr[N << 2];void pushup(int i) { tr[i].sum = tr[i << 1].sum + tr[i << 1 | 1].sum; }void pushdown(int i, int l, int r) { if (tr[i].lazy != -1) { tr[i << 1].lazy = tr[i].lazy; tr[i << 1 | 1].lazy = tr[i].lazy; ll mid = (l + r) >> 1; tr[i << 1].sum = tr[i].lazy * (mid - l + 1); tr[i << 1 | 1].sum = tr[i].lazy * (r - mid); tr[i].lazy = -1; }}void build(int i, int l, int r) { tr[i].lazy = -1; if (l == r) tr[i].sum = 0; else { ll mid = (l + r) >> 1; build(i << 1, l, mid); build(i << 1 | 1, mid + 1, r); pushup(i); }}void update(int i, int l, int r, int ql, int qr, int x) { if (ql > r || qr < l) return ; if (ql <= l && r <= qr) { tr[i].sum = (r - l + 1) * x; tr[i].lazy = x; } else { pushdown(i, l, r); ll mid = (l + r) >> 1; update(i << 1, l, mid, ql, qr, x); update(i << 1 | 1, mid + 1, r, ql, qr, x); pushup(i); }}//----------void query(int u, int v, int x) { while (top[u] != top[v]) { if (dep[top[u]] < dep[top[v]]) swap(u, v); update(1, 1, n, tid[top[u]], tid[u], x); u = fa[top[u]]; } if (dep[u] > dep[v]) swap(u, v); update(1, 1, n, tid[u], tid[v], x);}int main() { memset(son, -1, sizeof(son)); int a; scanf("%d", &n); for (int i = 1; i < n; i ++) scanf("%d", &a), add(a, i); dfs1(0, 0, 1), dfs2(0, 0); build(1, 1, n); int q; scanf("%d", &q); while (q --) { char c[10]; int x; cin >> c; scanf("%d", &x); int t1 = tr[1].sum; if (c[0] == 'i') { query(0, x, 1); int t2 = tr[1].sum; printf("%d\n", abs(t2 - t1)); } else if (c[0] == 'u') { update(1, 1, n, tid[x], tid[x] + size[x] - 1, 0); int t2 = tr[1].sum; printf("%d\n", abs(t2 - t1)); } } return 0; }
阅读全文
0 0
- 【NOI 2015 软件包管理器】【树剖】
- NOI 2015 软件包管理器
- bzoj-4196 NOI-2015 软件包管理器
- NOI 2015 DAY1 T2 软件包管理器 树链剖分
- 【树链剖分】【NOI 2015】【bzoj 4196】软件包管理器
- NOI 2015 day1 T2 软件包管理器
- NOI 2015 d1t2 洛谷 【P2146】 软件包管理器
- NOI 2015 软件包管理器 题解&代码
- NOI 2015 day1 t2 软件包管理器 题解&代码(c++)
- NKOJ 3423 (NOI 2015) 软件包管理器 (树链剖分+线段树)
- 【树链剖分】[BZOJ 4196][NOI 2014]软件包管理器
- codevs4621软件包管理器[树剖]
- 软件包管理器
- NOI2015 软件包管理器 树剖+线段树
- dpkg软件包管理器
- 软件包管理器yum
- ubuntu软件包管理器
- linux rpm软件包管理器
- 模糊图像退化与去模糊的数学模型
- <每日一题>最大回文子字符串
- springMVC容器和Spring容器
- unity3d保存文件到本地and加载本地文件
- Struts2的Ajax输入校验
- 【NOI 2015 软件包管理器】【树剖】
- 算法爱好者——删除数字 ? 待解决
- 有个疑问opencv保存的视频在哪里呢 如何去电脑文件里找到
- 中共中央办公厅 国务院办公厅印发《推进互联网协议第六版(IPv6)规模部署行动计划》
- AJAX处理数据提交到Servlet
- es6基础篇
- 每日一练-13
- Struts2校验
- Java jxl在excel模板中动态加入数据,及前端下载excel的例子