您的位置:首页 > 其它

【bzoj4196】[Noi2015]软件包管理器

2016-03-29 22:18 281 查看
裸的树链剖分。

对于安装 查询和维护到根路径

对于卸载 查询和维护子树信息

一开始线段树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
,siz
,top
,son
;
int pos
,r
;
LL sum[N<<2],add[N<<2];

struct Node
{
int to,next;
}e
;
int head
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: