bzoj4196[Noi2015]软件包管理器
Posted YJY_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4196[Noi2015]软件包管理器相关的知识,希望对你有一定的参考价值。
裸的树链剖分。
对于安装 查询和维护到根路径
对于卸载 查询和维护子树信息
一开始线段树add[]标记要全赋值为-1
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using
namespace
std;
typedef
long
long
LL;
#define N 200010
int
id;
int
fa[N],siz[N],top[N],son[N];
int
pos[N],r[N];
LL sum[N<<2],add[N<<2];
struct
Node
{
int
to,next;
}e[N];
int
head[N];
int
cnt;
int
a;
char
s;
int
n,q;
int
read()
{
int
x=0,f=1;
char
ch=
getchar
();
while
(ch<
‘0‘
||ch>
‘9‘
){
if
(ch==
‘-‘
)f=-1;ch=
getchar
();}
while
(ch>=
‘0‘
&&ch<=
‘9‘
){x=x*10+ch-
‘0‘
;ch=
getchar
();}
return
x*f;
}
void
link(
int
x,
int
y)
{
e[++cnt]=(Node){y,head[x]};
head[x]=cnt;
}
void
dfs(
int
x)
{
siz[x]=1;
for
(
int
i=head[x],mx=0;i;i=e[i].next)
if
(e[i].to!=fa[x])
{
fa[e[i].to]=x;
dfs(e[i].to);
siz[x]+=siz[e[i].to];
if
(siz[e[i].to]>mx)
mx=siz[e[i].to],son[x]=e[i].to;
}
}
void
dfs2(
int
x,
int
cha)
{
top[x]=cha;
pos[x]=++id;
if
(son[x])
dfs2(son[x],cha);
for
(
int
i=head[x];i;i=e[i].next)
if
(e[i].to!=fa[x] && e[i].to!=son[x])
dfs2(e[i].to,e[i].to);
r[x]=id;
}
void
pushup(
int
now)
{
sum[now]=sum[now<<1]+sum[now<<1|1];
}
void
pushdown(
int
nowl,
int
nowr,
int
now,
int
mid)
{
if
(add[now]!=-1)
{
LL t=add[now];
add[now]=-1;
add[now<<1]=t;
add[now<<1|1]=t;
sum[now<<1]=t*(mid-nowl+1);
sum[now<<1|1]=t*(nowr-mid);
}
}
void
update(
int
nowl,
int
nowr,
int
now,
int
s,
int
t,LL d)
{
if
(nowl>=s && nowr<=t)
{
add[now]=d;
sum[now]=(nowr-nowl+1)*d;
return
;
}
int
mid=(nowl+nowr)>>1;
pushdown(nowl,nowr,now,mid);
if
(s<=mid)
update(nowl,mid,now<<1,s,t,d);
if
(t>mid)
update(mid+1,nowr,now<<1|1,s,t,d);
pushup(now);
}
int
query(
int
nowl,
int
nowr,
int
now,
int
s,
int
t)
{
if
(nowl>=s && nowr<=t)
return
sum[now];
int
mid=(nowl+nowr)>>1;
int
ans=0;
pushdown(nowl,nowr,now,mid);
if
(s<=mid)
ans+=query(nowl,mid,now<<1,s,t);
if
(t>mid)
ans+=query(mid+1,nowr,now<<1|1,s,t);
return
ans;
}
int
work1(
int
x)
{
int
ans,res=0;
while
(x)
{
ans=query(1,n,1,pos[top[x]],pos[x]);
res+=pos[x]-pos[top[x]]+1-ans;
update(1,n,1,pos[top[x]],pos[x],1);
if
(ans)
break
;
x=fa[top[x]];
}
return
res;
}
int
work2(
int
x)
{
int
res;
res=query(1,n,1,pos[x],r[x]);
update(1,n,1,pos[x],r[x],0);
return
res;
}
int
main()
{
n=read();
for
(
int
i=1;i<n;i++)
{
a=read();
link(a+1,i+1);
}
dfs(1);
dfs2(1,1);
memset
(add,-1,
sizeof
(add));
q=read();
while
(q--)
{
scanf
(
"%c"
,&s);
a=read();
if
(s==
‘i‘
)
printf
(
"%d\n"
,work1(a+1));
else
printf
(
"%d\n"
,work2(a+1));
}
return
0;
}
以上是关于bzoj4196[Noi2015]软件包管理器的主要内容,如果未能解决你的问题,请参考以下文章
bzoj4196 [Noi2015]软件包管理器——树链剖分
Bzoj 4196: [Noi2015]软件包管理器 树链剖分
[UOJ#128][BZOJ4196][Noi2015]软件包管理器