BZOJ4196: [Noi2015]软件包管理器(树链剖分)
Description
Linux用户和OSX用户一定对软件包管理器不会陌生。通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件包的安装所依赖的其它软件包),完成所有的配置。Debian/Ubuntu使用的apt-get,Fedora/CentOS使用的yum,以及OSX下可用的homebrew都是优秀的软件包管理器。
Input
输入文件的第1行包含1个正整数n,表示软件包的总数。软件包从0开始编号。
Output
输出文件包括q行。
Sample Input
0 0 0 1 1 5
5
install 5
install 6
uninstall 1
install 4
uninstall 0
Sample Output
1
3
2
3
解题思路:
显然这是一棵树。
支持询问到根节点有多少点被标记,清空子树标记。
一颗线段树,支持区间改为1/0。
维护树链剖分序即可。
然而被卡常,开了O2才过,好蒟蒻啊QAQ
代码:
#pragma GCC optimize(2)
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lll spc<<1
#define rrr spc<<1|1
inline int read()
{
int l=;
int ret=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-')
l=-l;
ch=getchar();
}
while(ch<=''&&ch>='')
{
ret=ret*+ch-'';
ch=getchar();
}
return ret*l;
}
struct trnt{
int val;
int len;
int lzt;
bool chg;
}tr[];
struct pnt{
int hd;
int fa;
int dp;
int tp;
int ind;
int mxs;
int wgt;
}p[];
struct ent{
int twd;
int lst;
}e[];
int cnt;
int n,m;
int dfn;
char cmd[];
void ade(int f,int t)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
}
void pushup(int spc)
{
tr[spc].val=tr[lll].val+tr[rrr].val;
tr[spc].len=tr[lll].len+tr[rrr].len;
return ;
}
void Add(int spc,int x)
{
tr[spc].val=tr[spc].len*x;
tr[spc].lzt=x;
tr[spc].chg=;
return ;
}
void pushdown(int spc)
{
if(tr[spc].chg)
{
Add(lll,tr[spc].lzt);
Add(rrr,tr[spc].lzt);
tr[spc].chg=;
}
return ;
}
void build(int l,int r,int spc)
{
if(l==r)
{
tr[spc].len=;
return ;
}
int mid=(l+r)>>;
build(l,mid,lll);
build(mid+,r,rrr);
pushup(spc);
return ;
}
void update(int l,int r,int ll,int rr,int spc,int v)
{
if(l>rr||ll>r)
return ;
if(ll<=l&&r<=rr)
{
Add(spc,v);
return ;
}
pushdown(spc);
int mid=(l+r)>>;
update(l,mid,ll,rr,lll,v);
update(mid+,r,ll,rr,rrr,v);
pushup(spc);
return ;
}
int query(int l,int r,int ll,int rr,int spc)
{
if(ll>r||l>rr)
return ;
if(ll<=l&&r<=rr)
return tr[spc].val;
pushdown(spc);
int mid=(l+r)>>;
return query(l,mid,ll,rr,lll)+query(mid+,r,ll,rr,rrr);
}
void Basic_dfs(int x,int f)
{
p[x].fa=f;
p[x].dp=p[f].dp+;
p[x].wgt=;
int maxs=-;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f)
continue;
Basic_dfs(to,x);
p[x].wgt+=p[to].wgt;
if(maxs<p[to].wgt)
{
maxs=p[to].wgt;
p[x].mxs=to;
}
}
return ;
}
void Build_dfs(int x,int top)
{
if(!x)
return ;
p[x].ind=++dfn;
p[x].tp=top;
Build_dfs(p[x].mxs,top);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].ind)
continue;
Build_dfs(to,to);
}
}
int Install(int x)
{
int ans=;
while(p[x].tp!=)
{
ans+=p[x].dp-p[p[x].tp].dp-query(,dfn,p[p[x].tp].ind,p[x].ind,)+;
update(,dfn,p[p[x].tp].ind,p[x].ind,,);
x=p[p[x].tp].fa;
}
ans+=p[x].dp-query(,dfn,p[].ind,p[x].ind,);
update(,dfn,p[].ind,p[x].ind,,);
return ans;
}
int Uninstall(int x)
{
int ans=query(,dfn,p[x].ind,p[x].ind+p[x].wgt-,);
update(,dfn,p[x].ind,p[x].ind+p[x].wgt-,,);
return ans;
}
int main()
{
n=read();
for(int i=;i<=n;i++)
{
int x=read();
x++;
ade(x,i);
ade(i,x);
}
dfn=;
Basic_dfs(,);
Build_dfs(,);
build(,dfn,);
m=read();
while(m--)
{
scanf("%s",cmd+);
int x=read();
x++;
if(cmd[]=='i')
printf("%d\n",Install(x));
else
printf("%d\n",Uninstall(x));
}
return ;
}
BZOJ4196: [Noi2015]软件包管理器(树链剖分)的更多相关文章
- [BZOJ4196][NOI2015]软件包管理器(树链剖分)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2166 Solved: 1253[Submit][Sta ...
- BZOJ4196[Noi2015]软件包管理器——树链剖分+线段树
题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个 ...
- bzoj4196 [Noi2015]软件包管理器——树链剖分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4196 树链剖分. 代码如下: #include<iostream> #inclu ...
- [Bzoj4196] [NOI2015] 软件包管理器 [树链剖分,线段树]
题解摘要:树链剖分后用线段树区间查询修改,对于安装软件,将改点到根的路径全部变为1,对于卸载软件,将子树清空.注意边界,编号是从0开始的,容易漏掉树根. 第一次写树剖- #include <io ...
- bzoj4196 [Noi2015]软件包管理器 树链剖分+线段树
先把树剖分了(又是dfs1.dfs2),然后区间求和.区间覆盖即可 难得的1A好(shui)题 ——写了那么多题,终于有一道是1A的了,加上上一次连续交了几遍A的程序,我的状态莫名好看啊233 总结: ...
- 【BZOJ4196】[Noi2015]软件包管理器 树链剖分
[Noi2015]软件包管理器 树链剖分 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从 ...
- BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1352 Solved: 780[Submit][Stat ...
- Bzoj 4196: [Noi2015]软件包管理器 树链剖分
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 721 Solved: 419[Submit][Statu ...
- bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2852 Solved: 1668[Submit][Sta ...
- 洛谷 P2146 [NOI2015]软件包管理器 树链剖分
目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 输出样例#1: 输入样例#2: 输出样例#2: 说明 说明 思路 AC代码 总结 题面 题目链接 P ...
随机推荐
- Spark修炼之道(高级篇)——Spark源代码阅读:第十二节 Spark SQL 处理流程分析
作者:周志湖 以下的代码演示了通过Case Class进行表Schema定义的样例: // sc is an existing SparkContext. val sqlContext = new o ...
- Centos7 ssh免密码登陆
摘要:安装openssl openssl-devel 不过有些centos自带 192.168.161.5 192.168.161.15 本版本用centos7 (192.168.161.5) yu ...
- 【实用篇】Android之应用程序实现自动更新功能
我个人用的是友盟提供的自动更新组件,因此在这里只描述如何实用友盟提供的组件来完成程序的自动更新,步骤如下: 1.登录友盟官网,点击注册一个友盟账号. 2.注册成功后将会自动进入到添加新应用界面,选择添 ...
- IIS 优化
http://www.cnblogs.com/wangjingblogs/archive/2013/02/27/2934706.html 通过对IIS7的配置进行优化,调整IIS7应用池的队列长度,请 ...
- 《三》build 快速创建模块
一.将build.php文件复制一份放在 application目录下 二.修改build.php文件代码 <?php return [ 'home' => [ //需要生成的目录 '__ ...
- Mysql学习总结(11)——MySql存储过程与函数
摘要:存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句.存储过程和函数可以避免开发人员重复的编写相同的SQL语句.而且,存储过程和函数是在 ...
- 4.2.2 MINUS
4.2.2 MINUS正在更新内容,请稍后
- Android 4.4 Fence在SurfaceFlinger中的应用
网上关于android.fence的资料好少啊.差点儿没有,可是这个机制又在GUI系统中起着关键的数据,于是自己通读源代码和凝视.与大家分享下Fence究竟是怎么回事? Fence即栅栏.栅栏的角色与 ...
- Boolean operations between triangle meshes
Boolean operations between triangle meshes eryar@163.com Abstract. Boolean operations is one of basi ...
- Impala数据处理(加载和存储)
不多说,直接上干货! Hive与Impala都是构建在Hadoop之上的数据查询工具,那么在实际的应用中,它们是如何加载和存储数据的呢? Hive和Impala存储和加载表,和所有的关系型数据库一样, ...