http://uoj.ac/problem/128 (题目链接)

题意

  给出一棵树,每个节点代表一个软件包,维护卸载和安装操作。若要卸载节点x,那么必须卸载它的子树上的所有软件包;若要安装节点x必须安装所有它的祖先。每次询问安装或卸载某个软件包一共需要安装或者卸载多少个软件包。

Solution

  很裸的树链剖分,0表示未安装,1表示已安装。安装操作很好处理对吧,每次对节点x到根节点这条路径进行查询和修改即可。对于卸载操作,由于子树的dfs序是连续的,我们维护dfs序,进入x的子树时的时间戳L[x],退出时的时间戳R[x],查询和修改线段树上L[x]与R[x]之间的值即可。

  不知为何UOJ上数组要开大2倍才能过。。

代码

// uoj128
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<queue>
#define MOD 1000000007
#define inf 2147483640
#define LL long long
#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
using namespace std; const int maxn=100010;
struct tree {int l,r,s,tag;}tr[maxn<<1];
struct edge {int to,next;}e[maxn<<1];
int head[maxn],pos[maxn],size[maxn],deep[maxn],son[maxn],bl[maxn],bin[31],fa[maxn][31],L[maxn],R[maxn];
int cnt,n,q,P;
char s[maxn]; void link(int u,int v) {
e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;
e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;
}
void build(int k,int s,int t) {
tr[k]=(tree){s,t,0,-1};
if (s==t) return;
int mid=(s+t)>>1;
build(k<<1,s,mid);
build(k<<1|1,mid+1,t);
}
void pushdown(int k) {
int v=tr[k].tag;
tr[k<<1].s=v*(tr[k<<1].r-tr[k<<1].l+1);tr[k<<1].tag=v;
tr[k<<1|1].s=v*(tr[k<<1|1].r-tr[k<<1|1].l+1);tr[k<<1|1].tag=v;
tr[k].tag=-1;
}
void update(int k,int s,int t,int v) {
int l=tr[k].l,r=tr[k].r;
if (l==s && r==t) {tr[k].s=v*(r-l+1);tr[k].tag=v;return;}
if (tr[k].tag!=-1) pushdown(k);
int mid=(l+r)>>1;
if (t<=mid) update(k<<1,s,t,v);
else if (s>mid) update(k<<1|1,s,t,v);
else update(k<<1,s,mid,v),update(k<<1|1,mid+1,t,v);
tr[k].s=tr[k<<1].s+tr[k<<1|1].s;
}
int query(int k,int s,int t) {
int l=tr[k].l,r=tr[k].r;
if (l==s && r==t) return tr[k].s;
if (tr[k].tag!=-1) pushdown(k);
int mid=(l+r)>>1;
if (t<=mid) return query(k<<1,s,t);
else if (s>mid) return query(k<<1|1,s,t);
else return query(k<<1,s,mid)+query(k<<1|1,mid+1,t);
}
void dfs1(int x) {
size[x]=1;
for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa[x][0]) {
deep[e[i].to]=deep[x]+1;
fa[e[i].to][0]=x;
dfs1(e[i].to);
size[x]+=size[e[i].to];
if (size[e[i].to]>size[son[x]] || son[x]==0) son[x]=e[i].to;
}
}
void dfs2(int x,int top) {
L[x]=pos[x]=++P;bl[x]=top;
if (son[x]) dfs2(son[x],top);
for (int i=head[x];i;i=e[i].next)
if (e[i].to!=son[x] && e[i].to!=fa[x][0]) dfs2(e[i].to,e[i].to);
R[x]=P;
}
int solve(int x,int f) {
int s=0;
while (bl[x]!=bl[f]) {
s+=query(1,pos[bl[x]],pos[x]);
update(1,pos[bl[x]],pos[x],1);
x=fa[bl[x]][0];
}
if (pos[x]>=pos[f]) s+=query(1,pos[f],pos[x]),update(1,pos[f],pos[x],1);
return s;
}
int main() {
scanf("%d",&n);
for (int x,i=1;i<n;i++) {
scanf("%d",&x);
link(i,x);
}
dfs1(0);
dfs2(0,0);
build(1,1,n);
scanf("%d",&q);
while (q--) {
int x;
scanf("%s%d",s,&x);
if (s[0]=='i') {
//int tmp=solve(x,0);
printf("%d\n",deep[x]+1-solve(x,0));
}
else {
int tmp=query(1,L[x],R[x]);
printf("%d\n",tmp);
update(1,L[x],R[x],0);
}
}
return 0;
}

  

  

【uoj128】 NOI2015—软件包管理器的更多相关文章

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

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

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

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

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

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

  4. [NOI2015]软件包管理器

    4621 [NOI2015]软件包管理器  题目等级 : 钻石 Diamond   题目描述 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过 ...

  5. BZOJ_4196_[Noi2015]软件包管理器_树链剖分

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

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

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

  7. 洛谷 P2146 [NOI2015]软件包管理器 解题报告

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

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

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

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

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

  10. [Luogu 2146] NOI2015 软件包管理器

    [Luogu 2146] NOI2015 软件包管理器 树剖好题. 通过对题目的分析发现,这些软件构成一棵树,\(0\) 是树根. 每下载一个软件,需要下载根到这个软件的路径上的所有软件: 每卸载一个 ...

随机推荐

  1. 准备NOIP2017 编辑距离问题 模板

    输入 第1行:字符串a(a的长度 <= 1000). 第2行:字符串b(b的长度 <= 1000). 输出   输出a和b的编辑距离   输入示例 kitten sitting 输出示例 ...

  2. BZOJ 1066 【SCOI2007】 蜥蜴

    Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为$1$,蜥蜴的跳跃距离是d,即蜥蜴可以跳 ...

  3. 翻译qmake文档 目录

    利用空闲时间把qmke的文档翻译出来,翻译水平有限,有些地方翻译的不好,请谅解, 如果您能指出来,我会很感激并在第一时候做出修改. 翻译qmake文档(一) qmake指南和概述 翻译qmake文档( ...

  4. 富文本KidnEditor在MVC中的应用

    最近看到很多网站后台都用到了富文本,包括自己所在的公司也是.公司用的KindEditor,所以就讲讲KindEditor.之前我也没学过,所以网上搜了一篇博文,直接转载如下(PS:完全以学习为目的哦~ ...

  5. 前端框架——BootStrap学习

    BootStrap简单总结下:1.栅格系统,能够很好的同时适应手机端和PC端(及传说中的响应式布局) 2.兼容性好 接下来是对BootStrap学习的一些基础案例总结和回顾: 首先引入:bootstr ...

  6. C# EventHandler and Delegate(委托的使用)

    委托的声明 public delegate void MyDelegate(string str); 注 1.委托的定义和方法的定义类似,只是在前面加了一个delegate,但委托不是方法,它是一种特 ...

  7. .NET中的GDI+

    GDI:Graphics Device Interface. System. Windows. Shapes 命名空间: 类 Ellipse 绘制一个椭圆. Line 在两个点之间绘制一条直线. Pa ...

  8. SpringMVC学习--数据回显

    简介 表单提交失败需要再回到表单页面重新填写,原来提交的数据需要重新在页面上显示. 简单数据类型 对于简单数据类型,如:Integer.String.Float等使用Model将传入的参数再放到req ...

  9. 对象关系映射ORM

    对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从效 ...

  10. Android数据格式解析对象JSON用法(转)

    地址:http://www.cnblogs.com/devinzhang/archive/2012/01/09/2317315.html 里面的重点: JSON解析案例     (1)解析Object ...