【题目链接】

点击打开链接

【算法】

树链剖分,子树的DFS序也是连续的一段

要注意细节!

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100000 struct SegmentTree {
int l,r,sum[],opt;
} tree[MAXN*]; int i,N,Q,x,num;
int depth[MAXN+],size[MAXN+],son[MAXN+],fa[MAXN+],
top[MAXN+],id[MAXN+];
string type;
vector<int> E[MAXN+]; template <typename T> inline void read(T &x) {
int f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
for (; isdigit(c); c = getchar()) x = x * + c - '';
x *= f;
} template <typename T> inline void write(T x) {
if (x < ) { putchar('-'); x = -x; }
if (x > ) write(x/);
putchar(x%+'');
} template <typename T> inline void writeln(T x) {
write(x);
puts("");
} inline void dfs1(int x) {
int i,y;
size[x] = ;
for (i = ; i < E[x].size(); i++) {
y = E[x][i];
if (y != fa[x]) {
fa[y] = x;
depth[y] = depth[x] + ;
dfs1(y);
size[x] += size[y];
if ((size[y] > size[son[x]]) || (!son[x])) son[x] = y;
}
}
} inline void dfs2(int x,int tp) {
int i,y;
top[x] = tp; id[x] = ++num;
if (son[x]) dfs2(son[x],tp);
for (i = ; i < E[x].size(); i++) {
y = E[x][i];
if ((y != fa[x]) && (y != son[x]))
dfs2(y,y);
}
} inline void build(int index,int l,int r) {
int mid;
tree[index].l = l; tree[index].r = r;
tree[index].opt = ;
tree[index].sum[] = r - l + ;
if (l == r) return;
mid = (l + r) >> ;
build(index*,l,mid); build(index*+,mid+,r);
} inline void pushdown(int index) {
if (tree[index].l == tree[index].r) return;
tree[index*].opt = tree[index].opt;
tree[index*].sum[tree[index].opt] = tree[index*].r - tree[index*].l + ;
tree[index*].sum[tree[index].opt^] = ;
tree[index*+].opt = tree[index].opt;
tree[index*+].sum[tree[index].opt] = tree[index*+].r - tree[index*+].l + ;
tree[index*+].sum[tree[index].opt^] = ;
} inline void pushup(int index) {
tree[index].sum[] = tree[index*].sum[] + tree[index*+].sum[];
tree[index].sum[] = tree[index*].sum[] + tree[index*+].sum[];
if (tree[index*].opt != tree[index*+].opt) {
tree[index].opt = -;
return;
}
if ((tree[index*].opt == -) || (tree[index*+].opt == -)) {
tree[index].opt = -;
return;
}
tree[index].opt = tree[index*].opt;
} void modify(int index,int l,int r,int val) {
int mid;
if (tree[index].opt != -) pushdown(index);
if ((tree[index].l == l) && (tree[index].r == r)) {
tree[index].sum[val] = r - l + ;
tree[index].sum[val^] = ;
tree[index].opt = val;
} else {
mid = (tree[index].l + tree[index].r) >> ;
if (mid >= r) modify(index*,l,r,val);
else if (mid + <= l) modify(index*+,l,r,val);
else {
modify(index*,l,mid,val);
modify(index*+,mid+,r,val);
}
pushup(index);
}
} inline int query(int index,int l,int r,int val) {
int mid;
if (tree[index].opt != -) pushdown(index);
if ((tree[index].l == l) && (tree[index].r == r)) return tree[index].sum[val];
else {
mid = (tree[index].l + tree[index].r) >> ;
if (mid >= r) return query(index*,l,r,val);
else if (mid + <= l) return query(index*+,l,r,val);
else return query(index*,l,mid,val) + query(index*+,mid+,r,val);
}
} inline int Install(int x) {
int tp = top[x],
ans = ;
while (tp) {
ans += query(,id[tp],id[x],);
modify(,id[tp],id[x],);
x = fa[tp]; tp = top[x];
}
ans += query(,,id[x],);
modify(,,id[x],);
return ans;
} inline int Uninstall(int x) {
int ans = query(,id[x],id[x]+size[x]-,);
modify(,id[x],id[x]+size[x]-,);
return ans;
} int main() { read(N); for (i = ; i < N; i++) {
read(x);
E[x].push_back(i);
} depth[] = ;
dfs1();
dfs2(,); build(,,num); read(Q);
while (Q--) {
cin >> type;
if (type == "install") {
read(x);
writeln(Install(x));
} else {
read(x);
writeln(Uninstall(x));
}
} return ;
}

【NOI 2015】软件包管理器的更多相关文章

  1. [NOI 2015]软件包管理器

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

  2. [bzoj 4196][NOI 2015]软件包管理器

    大概算是一道模板题吧? 就是细节有点多 罗列一下: 如果习惯从1开始搞树的编号的话,处理输入进来的那个依赖关系在加边的时候两个都要+1,体现在代码就是i要从2枚举到n,然后输入进来的那个数要+1 这道 ...

  3. BZOJ4196 软件包管理器

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

  4. 【NOI2015】软件包管理器

    NOI难得的水题,话说还是T2诶……又学到了线段树的一种新的魔性使用 看sxysxy大神的代码才写出来的,sxysxy_orz 原题: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包 ...

  5. BZOJ4196 [Noi2015]软件包管理器 【树剖】

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

  6. [bzoj4196][Noi2015]软件包管理器_树链剖分_线段树

    软件包管理器 bzoj-4196 Noi-2015 题目大意:Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件 ...

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

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

  8. [BZOJ4196][NOI2015]软件包管理器

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

  9. Mac 系统下类似于 apt-get 的软件包管理器 -- Homebrew

    对于一个习惯了在 Ubuntu 的终端上通过 apt-get 来安装工具软件的我来说,也希望在Mac上找到类似的工具,能很方便的一条命令就能安装所需的软件,而不用手工的去查找下载编译,或者是折腾安装所 ...

  10. Chocolatey:Windows软件包管理器

    Chocolatey 2016-08-03 https://chocolatey.org/ Chocolatey是一个Windows软件包管理器,就像Nuget或者npm,或者说类似Linux上的ap ...

随机推荐

  1. 51 NOD 1383 整数分解为2的幂

    设f[i]为i这个数的划分方案,则: 1.i是奇数的时候,最前面只能放1,所以f[i] = f[i-1] 2.i是偶数的时候,最前面可以放1也可以不放1,而不放1的时候数列都是偶数所以 f[i] = ...

  2. SQL Server I/O Basics

     SQL Server I/O Basics Chapter 1http://www.microsoft.com/technet/prodtechnol/sql/2000/maintain/sqlIO ...

  3. 【postman】安装使用说明

    1.下载 下载地址:https://pan.baidu.com/s/1miyYjig?errno=0&errmsg=Auth%20Login%20Sucess&&bduss=& ...

  4. bootstrap -- 学习之流动布局

    Grid是什么? Grid 翻译成中文是格栅系统,不过还是不好理解,理解为一行12个格子可能更容易些.Grid可以把一行内容最多分成12个格子,而且可以根据需要来合并这12个格子中的其中某些格子.下面 ...

  5. gdb生成的core文件位置

    gdb可以生成core文件,记录堆栈信息,core文件名字是下面这种格式 :core.9488,其中9488是PID 文件位置是当前目录

  6. CocoaPods为project的全部target添加依赖支持

    在使用CocoaPods时.pod install默认仅仅能为xcodeproject的第一个target加入依赖库支持.假设要为全部的target添加可依照例如以下步骤进行 两种情 1. 编辑Pod ...

  7. Mysql学习记录点

    order by 数字,表示按照第几列来排序,可以从1开始,不能是0,也不能超过列数.

  8. bash 文件头尾插入字符

    头部插入:sed -i '1i\Insert this line' file.txt 尾部插入:echo "hehe"  >> tmp.txt

  9. [WASM Rust] Use the js-sys Crate to Invoke Global APIs Available in Any JavaScript Environment

    js-sys offers bindings to all the global APIs available in every JavaScript environment as defined b ...

  10. SolidEdge如何快速绘制并完全定义槽型孔

    如果你点击A之后形成的圆弧不是你想要的   你试着换个方向,如下图所示   有时候只有一个方形可以形成你要的半圆