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. GridView EmptyDataTemplate 动态显示

    以下语句加在GridView.DataBind()之后: Table GridViewTable = ((Table)gvGridView.Controls[]); if (!isSearch) (( ...

  2. 招聘 微软全球技术支持中心 sql server组

    微软亚太区全球技术支持中心(APGC CSS)是微软为个人用户.开发者.IT 专业人员到合作伙伴和企业级合作伙伴提供全方位.多元化的服务和技术支持的部门.一个优秀的SQL Server技术支持工程师应 ...

  3. AR 不同 继承映射的问题总结

    在使用AR(Nhibernate) 做ORM时,使用类的继承体系时,它有不同的映射方式,解决的问题不同,带来的问题差异也很大. 1.所有数据 存储在一张表,不同的类使用 DiscriminatorCo ...

  4. Handler 消息传递机制

    1,Handler 的概念Handler 是用来干什么的?1)执行计划任务,可以在预定的时间执行某些任务,可以模拟定时器 2)线程间通信.在Android的应用启动时,会创建一个主线程,主线程会创建一 ...

  5. JAVA CDI 学习(5) - 如何向RESTFul Service中注入EJB实例

    RESTFul Service中如果要注入EJB实例,常规的@Inject将不起作用,在Jboss中,应用甚至都启动不起来(因为@Inject注入失败),解决方法很简单:将@Inject换成@EJB ...

  6. 走进 Spring IOC 的世界

    转载出自:http://blog.csdn.net/m13666368773/article/details/7802126 1. IoC理论的背景我们都知道,在采用面向对象方法设计的软件系统中,它的 ...

  7. opencv1-安装及资料

    本科用过opencv2..3.1版本,当时按照 http://wiki.opencv.org.cn/index.php/首页 上面的步骤安装的,而且使用的是IplImage和CvMat等C接口的的AP ...

  8. 读懂IL代码就这么简单(二)

    一 前言 IL系列 第一篇写完后 得到高人指点,及时更正了文章中的错误,也使得我写这篇文章时更加谨慎,自己在了解相关知识点时,也更为细致.个人觉得既然做为文章写出来,就一定要保证比较高的质量,和正确率 ...

  9. 用RxJava处理嵌套请求

    用RxJava处理嵌套请求 互联网应用开发中由于请求网络数据频繁,往往后面一个请求的参数是前面一个请求的结果,于是经常需要在前面一个请求的响应中去发送第二个请求,从而造成"请求嵌套" ...

  10. Java学习笔记(二二)——Java HashMap

    [前面的话] 早上起来好瞌睡哈,最近要注意一样作息状态.       HashMap好好学习一下. [定义] Hashmap:是一个散列表,它存储的内容是键值对(key——value)映射.允许nul ...