您的位置:首页 > 其它

bzoj4196 [Noi2015]软件包管理器

2016-04-20 01:42 411 查看
  没啥可说的,树链剖分

  代码

#include<cstdio>
#define N 1000010
int dp,pre
,p
,tt
,size
,f
,gf
;
int l
,r
,go
,v
,s
,tot,m;
int L
,R
,n,a,i;
char str[10];
void link(int x,int y)
{
dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
}
void dfs1(int x,int fa)
{
int i=p[x];
size[x]=1;
while (i)
{
dfs1(tt[i],x);
size[x]+=size[tt[i]];
f[tt[i]]=x;
if (size[tt[i]]>size[go[x]]) go[x]=tt[i];
i=pre[i];
}
}
void dfs2(int x,int fa)
{
int i=p[x];
L[x]=++tot;
gf[x]=fa;
if (go[x]) dfs2(go[x],fa);
while (i)
{
if (tt[i]!=go[x]) dfs2(tt[i],tt[i]);
i=pre[i];
}
R[x]=tot;
}
void build(int x,int a,int b)
{
l[x]=a;r[x]=b;
if (b-a>1)
{
int m=(l[x]+r[x])>>1;
build(2*x,a,m);
build(2*x+1,m,b);
}
}
void clean(int x)
{
if (v[x]!=-1)
{
s[x]=(r[x]-l[x])*v[x];
v[2*x]=v[x];
v[2*x+1]=v[x];
v[x]=-1;
}
}
void change(int x,int a,int b,int c)
{
clean(x);
if ((a<=l[x])&&(r[x]<=b))
{
v[x]=c;
return;
}
int m=(l[x]+r[x])>>1;
if (a<m) change(2*x,a,b,c);
if (m<b) change(2*x+1,a,b,c);
clean(2*x);clean(2*x+1);
s[x]=s[2*x]+s[2*x+1];
}
int query(int x,int a,int b)
{
clean(x);
if ((a<=l[x])&&(r[x]<=b))
return s[x];
int m=(l[x]+r[x])>>1,ans=0;
if (a<m) ans+=query(2*x,a,b);
if (m<b) ans+=query(2*x+1,a,b);
return ans;
}
int getans(int x)
{
int ans=0;
while (x)
{
//    printf("%d %d\n",L[gf[x]],L[x]);
ans=ans+(L[x]-L[gf[x]]+1)-query(1,L[gf[x]]-1,L[x]);
change(1,L[gf[x]]-1,L[x],1);
x=f[gf[x]];
}
return ans;
}
int main()
{
scanf("%d",&n);
for (i=2;i<=n;i++)
{
scanf("%d",&a);a++;
link(a,i);
}
dfs1(1,0);
dfs2(1,1);
build(1,0,tot);
scanf("%d",&m);
for (i=1;i<=m;i++)
{
scanf("%s %d",str,&a);a++;
if (str[0]=='i')
printf("%d\n",getans(a));
else
{
//    printf("%d %d\n",L[a],R[a]);
printf("%d\n",query(1,L[a]-1,R[a]));
change(1,L[a]-1,R[a],0);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: