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]软件包管理器 树链剖分

bzoj4196: [Noi2015]软件包管理器

[UOJ#128][BZOJ4196][Noi2015]软件包管理器

bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

bzoj4196[Noi2015]软件包管理器