第一次做树剖

找同学要了模板 + 各种借鉴

先用dfs在划分轻重链并编号, install的时候就从查询的节点到根寻找标记的点有多少个,再用深度减去标记的点的个数,并把路径上所有点都标记

uninstall就是搜索查询的点的子树的标记个数,并取消所有的标记。

代码如下

 /**************************************************************
Problem: 4196
Language: C++
Result: Accepted
Time:8312 ms
Memory:7416 kb
****************************************************************/ #include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
#define g(l, r) (l + r | l != r)
#define o g(l, r)
#define ls g(l, mid)
#define rs g(mid + 1, r)
const int N = ; int n, dep[N], fa[N], hs[N], size[N], top[N], pos[N], mark[N<<], sum[N<<], tot, L, R, m;
vector < int > edge[N]; inline void dfs1(int u, int d, int f){
dep[u] = d; fa[u] = f; hs[u] = -; size[u] = ;
int tmp = ;
for (int i = ; i < edge[u].size(); i++){
int &v = edge[u][i];
dfs1(v, d + , u);
if (size[v] > tmp)
hs[u] = v, tmp = size[v];
size[u] += size[v];
}
} inline void dfs2(int u, int T){
top[u] = T; pos[u] = ++tot;
if (hs[u] == -) return ;
dfs2(hs[u], T);
for (int i = ; i < edge[u].size(); i++){
int &v = edge[u][i];
if (hs[u] == v) continue;
dfs2(v, v);
}
} inline void push(int l, int r) {
if (mark[o] == -) return;
int mid = l + r >> ;
if (l < r) {
mark[ls] = mark[o];
sum[ls] = mark[o] * (mid - l + );
mark[rs] = mark[o];
sum[rs] = mark[o] * (r - (mid + ) + );
}
mark[o] = -;
} void modify(int l, int r){
if (L <= l && r <= R){
sum[o] = m * (r - l + );
mark[o] = m;
return ;
}
push(l, r);
int mid = l + r >> ;
if (L <= mid) modify(l, mid);
if (R >= mid + ) modify(mid + , r);
sum[o] = sum[ls] + sum[rs];
} int getSum(int l, int r){
if (L <= l && r <= R){
return sum[o];
}
push(l, r);
int mid = l + r >> , ans = ;
if (L <= mid) ans += getSum(l, mid);
if (R >= mid + ) ans += getSum(mid + , r);
return ans;
} inline void install(int u){
int f = top[u], ans = dep[u];
m = ;
while(f){
L = pos[f], R = pos[u];
ans -= getSum(, tot);
modify(, tot);
u = fa[f]; f = top[u];
}
L = pos[f], R = pos[u];
ans -= getSum(, tot);
modify(, tot);
printf("%d\n", ans);
} inline void uninstall(int u){
L = pos[u], R = pos[u] + size[u] - , m = ;
int ans = getSum(, tot);
modify(, tot);
printf("%d\n", ans);
} int main(){
scanf("%d", &n);
for (int i = ; i < n; i++){
int x; scanf("%d", &x);
edge[x].push_back(i);
}
dfs1(, , -); dfs2(, );
int q;
scanf("%d", &q);
memset(mark, 0xff, sizeof(mark));
while(q--){
char str[]; int x;
scanf("%s%d", str, &x);
if (*str == 'i') install(x);
else uninstall(x);
}
return ;
}

bzoj 4196:[NOI2015] 软件包管理器 (树链剖分)的更多相关文章

  1. BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1352  Solved: 780[Submit][Stat ...

  2. Bzoj 4196: [Noi2015]软件包管理器 树链剖分

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 721  Solved: 419[Submit][Statu ...

  3. bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2852  Solved: 1668[Submit][Sta ...

  4. 【BZOJ4196】[Noi2015]软件包管理器 树链剖分

    [Noi2015]软件包管理器 树链剖分 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从 ...

  5. [BZOJ4196][NOI2015]软件包管理器(树链剖分)

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2166  Solved: 1253[Submit][Sta ...

  6. 洛谷 P2146 [NOI2015]软件包管理器 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 输出样例#1: 输入样例#2: 输出样例#2: 说明 说明 思路 AC代码 总结 题面 题目链接 P ...

  7. 【bzoj4196】[Noi2015]软件包管理器 树链剖分+线段树

    题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个 ...

  8. NOI2015 软件包管理器(树链剖分+线段树)

    P2146 软件包管理器 题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决 ...

  9. BZOJ4196[Noi2015]软件包管理器——树链剖分+线段树

    题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个 ...

  10. bzoj4196 [Noi2015]软件包管理器——树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4196 树链剖分. 代码如下: #include<iostream> #inclu ...

随机推荐

  1. py二级习题(猜猜我心中的数字)

    import random number = random.randint(1,100) while True: inputnumber = int(input("请输入你心中的数字:&qu ...

  2. 06-SV随机化

    1.受约束的随机测试法(CRT) 随着设计变得越来越大,要产生一个完整的激励集来测试设计的功能变得越来越困难.解决的办法是采用受约束的随机测试法自动产生测试集.CRT环境比定向测试的环境复杂,不仅需要 ...

  3. Oracle Solaris 10 重启后提示 Bad PBR sig

    Solaris 10 安装完毕重启后提示 Bad PBR sig 在磁盘分区的时候,默认自带的 overlap 不要删除,否则启动报错. 分区时,保留overlap(默认显示总容量大小)分区.安装操作 ...

  4. 最短路-A - 畅通工程续

    A - 畅通工程续 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这 ...

  5. 常用网络命令 在windows下

    1.增加一条临时静态路由 格式:route add <目的网络地址> mask <目的网络子网掩码> <网关> 实例:route add 0.0.0.0 mask ...

  6. [Python]BeautifulSoup标签的遍历

    1.下行遍历 标签树的下行遍历.content 子节点列表,将tag所有儿子节点存入列表.children 子节点的迭代类型,与.contents类似用于循环遍历儿子节点.descendants 子孙 ...

  7. ubuntu set up 2 - 双系统时间问题

    http://ubuntuhandbook.org/index.php/2016/05/time-differences-ubuntu-1604-windows-10/ For users who d ...

  8. [USACO12FEB] 附近的牛 Nearby Cows - 树形dp,容斥

    给你一棵 \(n\) 个点的树,点带权,对于每个节点求出距离它不超过 \(k\) 的所有节点权值和 \(m_i\) 随便定一个根,设\(f[i][j]\)表示只考虑子树,距离为\(j\)的权值和,\( ...

  9. linux - 查看 python 版本

    命令 python -V 结果

  10. Controller-->View传值的几种方法

    Controller --- > View 传值的方法 ViewBag ViewData TempData 向普通View页面传一个Model对象 向强类型页面传传一个Model对象 用一个Vi ...