【uoj128】 NOI2015—软件包管理器
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—软件包管理器的更多相关文章
- BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1352 Solved: 780[Submit][Stat ...
- [BZOJ4196][NOI2015]软件包管理器
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1040 Solved: 603[Submit][Stat ...
- Bzoj 4196: [Noi2015]软件包管理器 树链剖分
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 721 Solved: 419[Submit][Statu ...
- [NOI2015]软件包管理器
4621 [NOI2015]软件包管理器 题目等级 : 钻石 Diamond 题目描述 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过 ...
- BZOJ_4196_[Noi2015]软件包管理器_树链剖分
BZOJ_4196_[Noi2015]软件包管理器_树链剖分 题意: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助 ...
- bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2852 Solved: 1668[Submit][Sta ...
- 洛谷 P2146 [NOI2015]软件包管理器 解题报告
P2146 [NOI2015]软件包管理器 题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软 ...
- 【BZOJ4196】[Noi2015]软件包管理器 树链剖分
[Noi2015]软件包管理器 树链剖分 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从 ...
- [BZOJ4196][NOI2015]软件包管理器(树链剖分)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2166 Solved: 1253[Submit][Sta ...
- [Luogu 2146] NOI2015 软件包管理器
[Luogu 2146] NOI2015 软件包管理器 树剖好题. 通过对题目的分析发现,这些软件构成一棵树,\(0\) 是树根. 每下载一个软件,需要下载根到这个软件的路径上的所有软件: 每卸载一个 ...
随机推荐
- BZOJ 1040 【ZJOI2008】 骑士
Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火 ...
- script实现的日期表示
function clockon(bgclock){ var now=new Date(); var year=now.getYear(); var month=now.getMonth(); var ...
- Theano2.1.5-基础知识之打印出theano的图
来自:http://deeplearning.net/software/theano/tutorial/printing_drawing.html Printing/Drawing Theano gr ...
- 求解区间最值 - RMQ - ST 算法介绍
解析 ST 算法是 RMQ(Range Minimum/Maximum Query)中一个很经典的算法,它天生用来求得一个区间的最值,但却不能维护最值,也就是说,过程中不能改变区间中的某个元素的值.O ...
- Common Issues Which Cause Roles to Recycle
This section lists some of the common causes of deployment problems, and offers troubleshooting tips ...
- hiho一下 第六十六周
题目链接:这是一道水爆了的广搜题 #include<iostream> #include<stdio.h> #include<algorithm> #include ...
- hdu1754 I hate it线段树模板 区间最值查询
题目链接:这道题是线段树,树状数组最基础的问题 两种分类方式:按照更新对象和查询对象 单点更新,区间查询; 区间更新,单点查询; 按照整体维护的对象: 维护前缀和; 维护区间最值. 线段树模板代码 # ...
- Win7激活工具|OEM小马激活
OEM小马激活,Win7激活. 免费下载:http://yunpan.cn/cmZ5DyDvXG2In 访问密码 7fcf
- [AJAX系列]$.get(url,[data],[fn],[type])
$.get(url,[data],[fn],[type]) 概述 通过远程HTTP GET请求载入信息 参数 url:待载入页眉的URL地址 data:待发送key/value参数 callback: ...
- 玩转WIN7的MKLINK
引言: 换了新电脑,终于再次使用上啦WIN7 ,经过一个周每天重装N次系统,终于弄好一个像样的系统啦.由于使用rt7lite对WIN7SP1官方整合包进行了适当精简,所以最终系统的稳定性还得经过一段时 ...