zoukankan      html  css  js  c++  java
  • [集训]Evocation

    题意

    一颗有根树,每个点有黑白两种颜色和阀值ai,若它的子树中(不包括自己)的黑色数量大于ai,则产生一点贡献。每次将一个点的颜色取反,求每次修改后的贡献。n,q<=1E5。


    思考

    树剖后直接分块就行了。复杂度约为O((n+q)sqrt(nlogn)),但似乎更小?


    代码

      1 #pragma GCC optimize 2
      2 #include<bits/stdc++.h>
      3 using namespace std;
      4 const int maxn=1E5+5;
      5 ///////////////////////////////////////////////////////////////////////////////
      6 int wait[maxn],wait_R[maxn],wait_C[maxn],wait_W[maxn];
      7 template<class T>inline void copy(T*A,T*B,int l,int r)
      8 {
      9     for(int i=l;i<=r;++i)
     10         A[i-l+1]=B[i];
     11 }
     12 struct block
     13 {
     14     int n,pos,layer,now;
     15     bool created;
     16     int*f,*c;
     17     block()
     18     {
     19         created=now=0;
     20     }
     21     void init(int x,int where,int*A)
     22     {
     23         if(created)
     24             delete f,delete c;
     25         created=1;
     26         for(int i=1;i<=x;++i)
     27             wait_R[i]=A[i],wait_C[i]=0;
     28         sort(wait_R+1,wait_R+x+1);
     29         int size=0;
     30         for(int i=1;i<=x;++i)
     31         {
     32             if(wait_R[i]!=wait_R[i-1]||i==1)
     33                 wait_W[++size]=wait_R[i];
     34             ++wait_C[size];
     35         }
     36         n=size;
     37         f=new int[n+2];
     38         c=new int[n+2];
     39         now=c[0]=f[0]=c[n+1]=f[n+1]=0;
     40         layer=where;
     41         pos=1;
     42         for(int i=1;i<=n;++i)
     43             f[i]=wait_W[i],c[i]=wait_C[i];
     44         while(f[pos]<layer)
     45             now+=c[pos],++pos;
     46     }
     47     inline int get()
     48     {
     49         return now;
     50     }
     51     inline void add()
     52     {
     53         if(layer+1==f[pos]+1)
     54             now+=c[pos],++pos;
     55         ++layer;
     56     }
     57     inline void remove()
     58     {
     59         if(pos&&layer-1==f[pos-1])
     60             now-=c[pos-1],--pos;
     61         --layer;
     62     }
     63 };
     64 struct sequence
     65 {
     66     int*a,*tag,*bel,*tail;
     67     block*B;
     68     int n,sqr,tot;
     69     void init(int x,int*A)
     70     {
     71         n=x;
     72         sqr=sqrt(n+0.5);
     73         a=new int[n+3];
     74         bel=new int[n+3];
     75         tag=new int[sqr+3];
     76         tail=new int[sqr+3];
     77         for(int i=0;i<=sqr+1;++i)
     78             tail[i]=tag[i]=0;
     79         a[0]=0;
     80         for(int i=1;i<=n;++i)
     81             a[i]=A[i];
     82         int L=1,R=sqr;
     83         B=new block[sqr+3];
     84         tot=0;
     85         while(L<=n)
     86         {
     87             int len=min(n,R)-L+1;
     88             copy(wait,a,L,min(n,R));
     89             B[++tot].init(len,0,wait);
     90             for(int i=L;i<=R;++i)
     91                 bel[i]=tot;
     92             tail[tot]=min(n,R);
     93             L+=sqr,R+=sqr;
     94         }
     95     }
     96     inline int get()
     97     {
     98         int sum=0;
     99         for(int i=1;i<=tot;++i)
    100             sum+=B[i].now;
    101         return sum;
    102     }
    103     inline void add(int x)
    104     {
    105         int i=1;
    106         for(i=1;bel[i]!=bel[x];i+=sqr)
    107             B[bel[i]].add();
    108         int L=i,R=tail[bel[x]];
    109         int len=R-L+1;
    110         for(int i=L;i<=R;++i)
    111             wait[i-L+1]=a[i]-B[bel[x]].layer;
    112         for(int i=L;i<=x;++i)
    113             --wait[i-L+1];
    114         for(int i=L;i<=R;++i)
    115             a[i]=wait[i-L+1];
    116         B[bel[x]].init(len,0,wait);
    117     }
    118     inline void remove(int x)
    119     {
    120         int i=1;
    121         for(i=1;bel[i]!=bel[x];i+=sqr)
    122             B[bel[i]].remove();
    123         int L=i,R=tail[bel[x]];
    124         int len=R-L+1;
    125         for(int i=L;i<=R;++i)
    126             wait[i-L+1]=a[i]-B[bel[x]].layer;
    127         for(int i=L;i<=x;++i)
    128             ++wait[i-L+1];
    129         for(int i=L;i<=R;++i)
    130             a[i]=wait[i-L+1];
    131         B[bel[x]].init(len,0,wait);
    132     }
    133     inline void addDot(int x,int y)
    134     {
    135         int i=1;
    136         while(bel[i]!=bel[x])
    137             i+=sqr;
    138         int L=i,R=tail[bel[x]];
    139         int len=R-L+1;
    140         for(int i=L;i<=R;++i)
    141             wait[i-L+1]=a[i]-B[bel[x]].layer;
    142         wait[x-L+1]+=y;
    143         for(int i=L;i<=R;++i)
    144             a[i]=wait[i-L+1];
    145         B[bel[x]].init(len,0,wait);
    146     }
    147 }S[maxn];
    148 ///////////////////////////////////////////////////////////////////////////////
    149 int n,q,a[maxn];
    150 int size,head[maxn*2];
    151 int sum[maxn],fa[maxn],son[maxn],top[maxn],where[maxn],dfn[maxn],low[maxn],ti;
    152 int tot,ans;
    153 bool c[maxn];
    154 struct edge
    155 {
    156     int to,next;
    157 }E[maxn*2];
    158 void dfs1(int u,int F)
    159 {
    160     fa[u]=F,sum[u]=1;
    161     for(int i=head[u];i;i=E[i].next)
    162     {
    163         int v=E[i].to;
    164         if(v==F)
    165             continue;
    166         dfs1(v,u);
    167         sum[u]+=sum[v];
    168         if(sum[son[u]]<sum[v])
    169             son[u]=v;
    170     }
    171 }
    172 void dfs2(int u,int F)
    173 {
    174     low[u]=dfn[u]=++ti;
    175     if(son[F]==u)
    176         top[u]=top[F];
    177     else
    178         top[u]=u;
    179     if(son[u])
    180     {
    181         dfs2(son[u],u);
    182         low[u]=low[son[u]];
    183     }
    184     for(int i=head[u];i;i=E[i].next)
    185     {
    186         int v=E[i].to;
    187         if(v==F||v==son[u])
    188             continue;
    189         dfs2(v,u);
    190         low[u]=low[v];
    191     }
    192 }
    193 void get(int u)
    194 {
    195     wait[where[u]=++tot]=a[u];
    196     if(son[u])
    197         get(son[u]);
    198 }
    199 void add(int u,int v)
    200 {
    201     E[++size].to=v;
    202     E[size].next=head[u];
    203     head[u]=size;
    204 }
    205 void addChain(int x)
    206 {
    207     while(x)
    208     {
    209         S[top[x]].add(where[x]);
    210         x=fa[top[x]];
    211     }
    212 }
    213 void removeChain(int x)
    214 {
    215     while(x)
    216     {
    217         S[top[x]].remove(where[x]);
    218         x=fa[top[x]];
    219     }
    220 }
    221 int askChain(int x)
    222 {
    223     int sum=0;
    224     while(x)
    225     {
    226         sum+=S[top[x]].get();
    227         x=fa[top[x]];
    228     }
    229     return sum;
    230 }
    231 ///////////////////////////////////////////////////////////////////////////////
    232 int main()
    233 {
    234     ios::sync_with_stdio(false);
    235     int num;
    236     cin>>num;
    237     cin>>n>>q;
    238     for(int i=2;i<=n;++i)
    239     {
    240         int x;
    241         cin>>x;
    242         add(x,i);
    243         add(i,x);
    244     }
    245     for(int i=1;i<=n;++i)
    246         cin>>a[i];
    247     dfs1(1,1);
    248     dfs2(1,1);
    249     fa[1]=0;
    250     for(int u=1;u<=n;++u)
    251         if(top[u]==u)
    252         {
    253             tot=0;
    254             get(u);
    255             S[u].init(tot,wait);
    256         }
    257     while(q--)
    258     {
    259         int x;
    260         cin>>x;
    261         if(c[x])
    262         {
    263             int last=askChain(x);
    264             removeChain(fa[x]);
    265             S[top[x]].addDot(where[x],-666666);
    266             int now=askChain(x);
    267             ans+=now-last;
    268         }
    269         else
    270         {
    271             int last=askChain(x);
    272             addChain(fa[x]);
    273             S[top[x]].addDot(where[x],666666);
    274             int now=askChain(x);
    275             ans+=now-last;
    276         }
    277         c[x]^=1;
    278         cout<<ans<<" ";
    279     }
    280     return 0;
    281 }
    View Code
  • 相关阅读:
    Java三大主流框架概述
    ASP.NET的内置对象
    9月29
    第一章
    在java开发中,为什么要使用单例模式。。?
    《设计模式之禅》一书学习心得(连载中)
    网上的一些java算法题的个人练习笔记
    第四次作业
    看《构建之法》有感
    实验四
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/11136218.html
Copyright © 2011-2022 走看看