• [NOI2015]软件包管理器(树链剖分)


    树链剖分 在jacktang的帮助下终于al。。。

    这道题剖分后用线段树维护一个sum和lazy就可以了;

    install操作就是询问x节点到根节点的路径上有多少0;然后全部置为1;

    uninstall操作就是询问x节点到根节点的路径上有多少1;然后全部置为0;

    修改的话直接暴力修改就可以了(暴力修改区间的sum和lazy);lazy下放的时候要特别小心;

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define ll long long
      5 using namespace std;
      6 const ll maxn=1e5+10;
      7 ll n,m,cnt,head[maxn],nod,size[maxn],pre[maxn],wson[maxn],dfn[maxn],d[maxn],fa[maxn],tp,sum[maxn<<2],lazy[maxn<<2],a[maxn];
      8 ll top[maxn];
      9 char s[maxn];
     10 struct Edge{
     11     ll v,nxt;
     12 }E[maxn<<1];
     13 inline ll read()
     14 {
     15     ll x=0,f=1;char c=getchar();
     16     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     17     while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
     18     return x*f;
     19 }
     20 inline ll max(ll a,ll b)
     21 {
     22     return a>b?a:b;
     23 }
     24 inline void addedge(ll u,ll v)
     25 {
     26     E[++cnt].v=v;
     27     E[cnt].nxt=head[u];
     28     head[u]=cnt;
     29 }
     30 inline void dfs1(ll u,ll f)
     31 {
     32     size[u]=1;d[u]=d[f]+1;
     33     for(ll i=head[u];i;i=E[i].nxt)
     34     {
     35         ll v=E[i].v;
     36         if(v==f)continue;
     37         dfs1(v,u);
     38         fa[v]=u;
     39         size[u]+=size[v];
     40         if(size[wson[u]]<size[v])wson[u]=v;
     41     }
     42 }
     43 inline void dfs2(ll u,ll tp)
     44 {
     45     top[u]=tp;dfn[u]=++nod;pre[nod]=u;
     46     if(wson[u])dfs2(wson[u],tp);
     47     for(ll i=head[u];i;i=E[i].nxt)
     48     {
     49         ll v=E[i].v;
     50         if(v==fa[u]||v==wson[u])continue;
     51         dfs2(v,v);
     52     }
     53 }
     54 inline void pushup(ll k){sum[k]=sum[k<<1]+sum[k<<1|1];}
     55 inline void pushdown(ll k,ll l,ll r)
     56 {
     57     ll mid=l+r>>1;
     58     lazy[k<<1]=lazy[k];lazy[k<<1|1]=lazy[k];
     59     sum[k<<1]=(mid-l+1)*max(lazy[k],0);sum[k<<1|1]=(r-mid)*max(lazy[k],0);
     60     lazy[k]=0;
     61 }
     62 inline void update(ll k,ll l,ll r,ll ql,ll qr,ll v)
     63 {
     64     ll mid=l+r>>1;
     65     if(l==ql&&r==qr){sum[k]=(qr-ql+1)*v;lazy[k]=(v==1?1:-1);return;}
     66     if(lazy[k]!=0)pushdown(k,l,r);
     67     if(qr<=mid)update(k<<1,l,mid,ql,qr,v);
     68     else if(ql>=mid+1)update(k<<1|1,mid+1,r,ql,qr,v);
     69     else update(k<<1,l,mid,ql,mid,v),update(k<<1|1,mid+1,r,mid+1,qr,v);
     70     pushup(k);
     71 }
     72 inline ll query_sum(ll k,ll l,ll r,ll ql,ll qr)
     73 {
     74     ll mid=l+r>>1;
     75     if(l==ql&&r==qr)return sum[k];
     76     if(lazy[k]!=0)pushdown(k,l,r);
     77     if(qr<=mid)return query_sum(k<<1,l,mid,ql,qr);
     78     else if(ql>=mid+1)return query_sum(k<<1|1,mid+1,r,ql,qr);
     79     else return query_sum(k<<1,l,mid,ql,mid)+query_sum(k<<1|1,mid+1,r,mid+1,qr);
     80     pushup(k);
     81 }
     82 inline ll install(ll x)
     83 {
     84     ll ans=0,tmp=x;
     85     while(top[x]!=top[1])
     86     {
     87         ans+=query_sum(1,1,n,dfn[top[x]],dfn[x]);
     88         update(1,1,n,dfn[top[x]],dfn[x],1);
     89         x=fa[top[x]];
     90     }
     91     ans+=query_sum(1,1,n,dfn[1],dfn[x]);
     92     update(1,1,n,dfn[1],dfn[x],1);
     93     return d[tmp]-ans;
     94 }
     95 inline ll uninstall(ll x)
     96 {
     97     ll ans=query_sum(1,1,n,dfn[x],dfn[x]+size[x]-1);
     98     update(1,1,n,dfn[x],dfn[x]+size[x]-1,0);
     99     return ans;
    100 }
    101 int main()
    102 {
    103 //    freopen("data.in","r",stdin);
    104 //    freopen("my.out","w",stdout);
    105     n=read();
    106     for(ll i=2;i<=n;++i)
    107     {
    108         ll a=read()+1;
    109         addedge(a,i);addedge(i,a);
    110     }
    111     m=read();
    112     dfs1(1,0);dfs2(1,1);
    113     for(ll i=1;i<=m;++i)
    114     {
    115         ll x;
    116         scanf("%s",s+1);x=read()+1;
    117         if(s[1]=='i')printf("%lld
    ",install(x));
    118         else if(s[1]=='u')printf("%lld
    ",uninstall(x));
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    nao机器人使用手册
    突然感觉简单的东西是最美的
    window10教育版激活失败
    linux新分区无法新建文件夹
    看看CSDN的吃相
    游戏mod启动器原理
    显示器选购指南
    维修老电视
    快乐小丑
    这猫会关水龙头,所以你只要给猫猫打开就行——华中师范大学的胖猫
  • 原文地址:https://www.cnblogs.com/fanyujun/p/9409759.html
Copyright © 2020-2023  润新知