代码改变世界

P2146 [NOI2015]软件包管理器

2019-11-22 14:45  一只弱鸡丶  阅读(110)  评论(0编辑  收藏  举报

题目链接:

这道题也是裸题0.0

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#include <tr1/unordered_map>
using namespace std;
#define ll long long
#define re register
#define pb push_back
#define fi first
#define se second
const int N=1e6+10;
const int mod=998244353;
void read(int &a)
{
    a=0;int d=1;char ch;
    while(ch=getchar(),ch>'9'||ch<'0')
        if(ch=='-')
            d=-1;
    a=ch^48;
    while(ch=getchar(),ch>='0'&&ch<='9')
        a=(a<<3)+(a<<1)+(ch^48);
    a*=d;
}
struct note{int l,r,ma,mi,lazy;}tree[N<<1];
int top[N],siz[N],cnt,rt=1,id[N],son[N],f[N],dep[N];
vector <int> v[N];
void dfs1(int x)
{
    siz[x]=1,dep[x]=dep[f[x]]+1;
    for(auto i:v[x])
    {
        if(i!=f[x])
        {
            f[i]=x,dfs1(i);
            siz[x]+=siz[i];
            if(siz[son[x]]<siz[i]) son[x]=i;
        }
    }
}
void dfs2(int x,int tp)
{
    top[x]=tp,id[x]=++cnt;
    if(son[x]) dfs2(son[x],tp);
    for(auto i:v[x]) if(i!=son[x]&&i!=f[x]) dfs2(i,i);
}
void build(int l,int r,int now)
{
    tree[now].l=l,tree[now].r=r,tree[now].lazy=-1;
    if(l==r) {tree[now].ma=1,tree[now].mi=0;return;}
    int m=l+r>>1;
    build(l,m,now<<1),build(m+1,r,now<<1|1);
    tree[now].ma=tree[now<<1].ma+tree[now<<1|1].ma;
    tree[now].mi=tree[now<<1].mi+tree[now<<1|1].mi;
}
void work(int now,int k)
{
    if(!k) tree[now].ma=tree[now].r-tree[now].l+1,tree[now].mi=0;
    else tree[now].ma=0,tree[now].mi=tree[now].r-tree[now].l+1;
    tree[now].lazy=k;
}
void pushdown(int now)
{
    work(now<<1,tree[now].lazy);
    work(now<<1|1,tree[now].lazy);
    tree[now].lazy=-1;
}
void modify(int l,int r,int now,int k)
{
    if(tree[now].l>=l&&tree[now].r<=r) {work(now,k);return;}
    if(tree[now].lazy!=-1) pushdown(now);
    int m=tree[now].l+tree[now].r>>1;
    if(m>=l) modify(l,r,now<<1,k);
    if(m<r) modify(l,r,now<<1|1,k);
    tree[now].ma=tree[now<<1].ma+tree[now<<1|1].ma;
    tree[now].mi=tree[now<<1].mi+tree[now<<1|1].mi;
}
int query(int l,int r,int now,int k)
{
    int ans=0;
    if(tree[now].l>=l&&tree[now].r<=r) {return k==1?tree[now].mi:tree[now].ma;}
    if(tree[now].lazy!=-1) pushdown(now);
    int m=tree[now].l+tree[now].r>>1;
    if(m>=l) ans+=query(l,r,now<<1,k);
    if(m<r) ans+=query(l,r,now<<1|1,k);
    return ans;
}
int update(int x,int y)///安装,ma是0的个数
{
    int ans=0;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        ans+=query(id[top[x]],id[x],1,0);
        modify(id[top[x]],id[x],1,1);
        x=f[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    ans+=query(id[x],id[y],1,0);
    modify(id[x],id[y],1,1);
    return ans;
}
char op[10];
int main()
{
    int n,m;read(n);
    for(re int i=2,x;i<=n;i++) read(x),x++,v[i].pb(x),v[x].pb(i);
    dfs1(rt),dfs2(rt,rt),build(1,n,1);
    read(m);
    for(re int i=1,x;i<=m;i++)
    {
        scanf("%s %d",op,&x);x++;
        if(op[0]=='i') printf("%d\n",update(x,1));
        else printf("%d\n",query(id[x],id[x]+siz[x]-1,1,1)),modify(id[x],id[x]+siz[x]-1,1,0);
    }
    return 0;
}