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. PAT 1002. 写出这个数 (20)

    读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式:每个测试输入包含1个测试用例,即给出自然数n的值.这里保证n小于10100. 输出格式:在一行内输出n的各位数字之和的每 ...

  2. 升级nodejs版本

    node有一个模块叫n,是专门用来管理node.js的版本的. 首先安装n模块: npm install -g n 第二步: 升级node.js到最新稳定版 n stable n后面也可以跟随版本号比 ...

  3. 031医疗项目-模块三:药品供应商目录模块——供货商药品目录查询功能----------sql补充知识

    这个补充知识有一个点很有必要,视屏上的老师提出一点: 内链接关联查询: 如果表A和表B有一个外键关联 ,可以通过外键进行内链接查询 select dictinfo.*, dicttype.typena ...

  4. 利用Spring MVC搭建REST Service

    之前写过一篇 利用JAX-RS快速开发RESTful 服务 今天来看下spring-mvc框架如何实现类似的功能: 一.pom.xml <?xml version="1.0" ...

  5. vmware安装cent os 6.5 + oracle 11g xe + jboss eap 6.2 + weblogic 12c+ webshpere mq 7.5

    前言: mac系统发展速度确实很快,短短数年,mac os上已经能网银支付(中行.招行.工商.支付宝等均已全面支持mac os了),windows上的经典常用软件:qq.飞信.旺旺.有道词典.有道云笔 ...

  6. C# FTP上传

    public class FtpHelper { public FtpHelper(string p_url, string p_user, string p_password) { if (!p_u ...

  7. 化茧成蝶,开源NetWorkSocket通讯组件

    前言 前后历时三年,期间大量参考.Net Framework和Asp.net MVC源代码,写写删删再重构,组件如今更新到V1.5.x了.从原来的丑小鸭,变成今天拥有稳定和强大的tcp协议支持基础层, ...

  8. 狗屎的Java规范

    规范 标题真有点侮辱了狗. 最近做Java,C#与Java对比笔记: http://www.cnblogs.com/newsea/p/4839540.html 其实Java语法弱点就弱点,关键是Jav ...

  9. checkbox js onclick ajax,列表页表格中修改数据

    <input type='checkBox' value='".$row["p_id"]."' onclick='changeisNew(this);'& ...

  10. 可扩展性 Scalability

    水平扩展和垂直扩展: Horizontal and vertical scaling Methods of adding more resources for a particular applica ...