#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+5;
int n,m;
int e,begin[maxn],next[maxn],to[maxn],val[maxn];
struct segment_tree{
int l,r,sum,mark;
}tree[maxn<<2];
int son[maxn],id[maxn],father[maxn],cnt,deep[maxn],size[maxn],top[maxn];
inline void add(int x,int y){
to[++e] = y;
next[e] = begin[x];
begin[x] = e;
}
inline void dfs1(int x,int fa,int dep){
deep[x] = dep;
father[x] = fa;
size[x] = 1;
int maxson = -1;
for(int i = begin[x];i;i = next[i]){
int y = to[i];
if(y == fa)continue;
dfs1(y,x,dep+1);
size[x] += size[y];
if(size[y] > maxson)son[x] = y,maxson = size[y];
}
}
inline void dfs2(int x,int ntop){
id[x] = ++cnt;
top[x] = ntop;
if(!son[x])return;
dfs2(son[x],ntop);
for(int i = begin[x];i;i = next[i]){
int y = to[i];
if(y == father[x] || y == son[x])continue;
dfs2(y,y);
}
}
inline void pushup(int root){
tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum;
}
inline void pushdown(int root){
if (tree[root].mark){
tree[root<<1].mark = tree[root].mark;
tree[root<<1|1].mark = tree[root].mark;
tree[root<<1].sum = (tree[root].mark-1)*(tree[root<<1].r-tree[root<<1].l+1);
tree[root<<1|1].sum = (tree[root].mark-1)*(tree[root<<1|1].r-tree[root<<1|1].l+1);
tree[root].mark = 0;
}
}
inline void build(int l,int r,int root){
tree[root].l = l;
tree[root].r = r;
if(l == r)return;
int mid = l+r>>1;
build(l,mid,root<<1);
build(mid+1,r,root<<1|1);
pushup(root);
}
inline void update(int l,int r,int ql,int qr,int root,int x){
if(ql > r || qr < l)return;
if(ql <= l && qr >= r){
tree[root].mark = x+1;
tree[root].sum = x*(r-l+1);
return;
}
pushdown(root);
int mid = l+r>>1;
update(l,mid,ql,qr,root<<1,x);
update(mid+1,r,ql,qr,root<<1|1,x);
pushup(root);
}
inline int query(int l,int r,int ql,int qr,int root){
if(ql > r || qr < l)return 0;
if(ql <= l && qr >= r)return tree[root].sum;
pushdown(root);
int mid = l+r>>1;
return query(l,mid,ql,qr,root<<1)+query(mid+1,r,ql,qr,root<<1|1);
}
inline int Query(int l,int r,int ql,int qr,int root){
if(ql > r || qr < l)return 0;
if(ql <= l && qr >= r)return (r-l+1)-tree[root].sum;
pushdown(root);
int mid = l+r>>1;
return Query(l,mid,ql,qr,root<<1)+Query(mid+1,r,ql,qr,root<<1|1);
}
inline void update_range(int u,int v,long long x){
while(top[u] != top[v]){
if(deep[top[u]] < deep[top[v]])swap(u,v);
update(1,cnt,id[top[u]],id[u],1,x);
u = father[top[u]];
}
if(deep[u] > deep[v])swap(u,v);
update(1,cnt,id[u],id[v],1,x);
}
inline int query_range(int u,int v){
int ans = 0;
while(top[u] != top[v]){
if (deep[top[u]] < deep[top[v]])swap(u,v);
ans += Query(1,cnt,id[top[u]],id[u],1);
u = father[top[u]];
}
if(deep[u] > deep[v])swap(u,v);
return ans+Query(1,cnt,id[u],id[v],1);
}
int main() {
cin>>n;
for(int i = 2,x;i <= n;i++){
cin>>x;
x++;
add(x,i);
}
dfs1(1,0,1);
dfs2(1,1);
build(1,cnt,1);
cin>>m;
while(m--){
string dispose;
int x;
cin>>dispose>>x;
x++;
if(dispose == "install"){
cout<<query_range(1,x)<<endl;
update_range(1,x,1);
}
else{
cout<<query(1,cnt,id[x],id[x]+size[x]-1,1)<<endl;
update(1,cnt,id[x],id[x]+size[x]-1,1,0);
}
}
return 0;
}

  树链剖分这东西我还是只会用一点点,所以讲不出来做法,有的题实在心态爆炸看别人代码会发现真的是细节决定成败,以后尽量可以把思路讲出来,现在的状况是:只可意会不可言传!!!~~~

[NOI2015]软件包管理器-树链剖分的更多相关文章

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

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

  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]软件包管理器(树链剖分)

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. XSS原理及防范

    Xss(cross-site scripting)攻击指的是攻击者往Web页面里插入恶意html标签或者javascript代码.比如:攻击者在论坛中放一个看似安全的链接,骗取用户点击后,窃取cook ...

  2. 【刷题】若串 =’software’ ,其子串数目为:37

    子串 子串是母串中的一部分,可以是母串本身,也可以是空字符串 设串中字符数为n,则其子串数目为:s=(1+n)*n/2+1 具体地: 长为0的子串:1 长为1的子串:8 长为2的子串:7 长为3的子串 ...

  3. rxjs一句话描述一个操作符(1)

    之前一直在写LINQ之类的东西,对于函数式的面向对象还是有一些功底,所以对于rxjs,感觉上不是很难,但是每次看完过几天就忘,还是记一下笔记吧,好记性不如烂笔头真不是盖的. 首先介绍几个重要的概念. ...

  4. Shell命令-文件及内容处理之more、less

    文件及内容处理 - more.less 1. more:分页显示文件内容 more命令的功能说明 more 命令类似 cat,不过会以一页一页的形式显示,更方便使用者逐页阅读,而最基本的指令就是按空白 ...

  5. MD 的常用语法格式

    参考资料:MarkDown 语言常用语法 注意:vscode 中,可以使用 ctrl + shift + v 进行预览: 一.标题 一般使用 # 来进行层级标识.共 6 个层级,再多不识别. #  = ...

  6. <Android基础> (五) 广播机制

    1)接收系统广播:a.动态注册监听网络变化 b.静态注册实现开机启动 2)发送自定义广播:a.发送标准广播 b.发送有序广播 3)使用本地广播 第五章 5.1 广播机制 Android中的每个程序都可 ...

  7. Java【初识篇】语言概述

    什么是计算机语言 语言:是人与人之间用于沟通的一种方式.例如:中国人与中国人用普通话沟通.而中国人要和英国人交流,就要学习英语.计算机语言(编程语言):人与计算机交流的方式.如果人要与计算机交流,那么 ...

  8. python学习day14 装饰器(二)&模块

    装饰器(二)&模块 #普通装饰器基本格式 def wrapper(func): def inner(): pass return func() return inner def func(): ...

  9. Win10激活工具

    W10数字许可激活C#版v2.8.0百度网盘下载地址:https://pan.baidu.com/s/1TD0PVxIfB2NTarAuP9NJbQ直接下载地址:FTP://A@OS.X6X8.COM ...

  10. 洛谷P1776 宝物筛选

    一道很好的单调队列优化多重背包入门题 令\(v[i]\)表示重量,\(w[i]\)表示价格 ,\(c[i]\)表示最多可放的数量,不难推出朴素的转移方程如下: \(f[i][j]=max\{f[i-1 ...