[Bjoi2018]二进制

题解:

首先发现性质

只有1个1的区间 或者 奇数个1且0的个数少于2这个区间是不合法的

然后这个东西暴力是比较好处理的

刚开始写的比较傻逼,分几种情况

先把0,1缩在一起

1.k1个0+1+k2个0

2.k1个1+0+k2个1 其中k1+k2是奇数

3.1之内单独1

4.0+奇数1

然后这样挺烦的

最讨厌写这种很容易漏掉的分类套路了。。

代码:

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define dep(i,t,h) for (int i=t;i>=h;i--) 
#define rep(i,h,t) for (int i=h;i<=t;i++)
#define ll long long
const int N=2e5;
int a[N],n,m,b[N],c[N],d[N],f[N];
IL ll js(int l)
{
  ll cnt=0; int jl=0;
  rep(k,1,l) if (b[k]==1) cnt++;
  b[0]=b[1]^1;
  rep(k,1,l)
    if (b[k]!=b[k-1]) c[++jl]=b[k],d[jl]=1;
    else d[jl]++;
  rep(i,1,jl)
    if (c[i]==1)
    {
      cnt+=f[d[i]];
      if (i>1) cnt+=(d[i]+1)/2;
      if (i<jl) cnt+=(d[i]+1)/2;
    }
  d[0]=d[jl+1]=0;
  rep(i,1,jl)
    if (c[i]==1)
    {
      if (d[i]==1) cnt+=1ll*d[i-1]*d[i+1];
      cnt+=max(d[i-1]-1,0);
      cnt+=max(d[i+1]-1,0);
    }
  rep(i,2,jl-1)
    if (c[i]==0&&d[i]==1)
    {
      cnt+=((d[i-1]+1)/2)*(d[i+1]/2)+(d[i-1]/2)*((d[i+1]+1)/2);
    }
  return 1ll*l*(l+1)/2-cnt;
}
int main()
{
  ios::sync_with_stdio(false);
  cin>>n;
  rep(i,1,n) cin>>a[i];
  rep(i,1,5000)
    rep(j,3,i)
      if (j%2==1) f[i]+=i-j+1;
  cin>>m;
  rep(i,1,m)
  {
    int kk,x,y;
    cin>>kk;
    if (kk==1)
    {
      cin>>x; a[x]^=1;
    } else
    {
      cin>>x>>y;
      int len=y-x+1;
      rep(j,x,y) b[j-x+1]=a[j];
      cout<<js(len)<<endl;
    }
  }
  return 0;
}

 

我们考虑dp

$f[i][[6]$分别对应

0:0个0,奇数个1

1:0个0,偶数个0

2:1个0,奇数个0

3:1个0,偶数个0

4:1个1,任意0

5:0个1,任意0

写之前觉得挺烦的 写了发现好像挺好写 比上面那个不知道好写到哪里去了

然后因为带修改,所以是动态dp

链上动态dp用线段树

树上动态dp用动态链分治(怎么随便做做到这么多动态dp。。)

考虑用线段树维护

我们得再用一维 表示这个是左边还是右边还是全部

另外注意一下这样我们重复计数了 就是两种情况都满足的时候

所以我们要01/10 以及1单独出现的

但其实1单独出现的时候值是我们给的 所以直接给1不给2就行了

但我写之前没想这个所以给了2然后用树状数组再维护了一下1的个数

注意维护01/10的时候一个位置能影响两边

除了updata其他都是模板

updata只要思路清晰还是挺好写的

所以这东西好像并不难写??

代码:

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (int i=h;i<=t;i++)
#define dep(i,t,h) for (int i=t;i>=h;i--)
#define me(x) memset(x,0,sizeof(x))
#define ll long long
#define mid ((h+t)>>1)
#define lowbit(x) (x&(-x))
namespace IO{
  char ss[1<<24],*A=ss,*B=ss;
  IL char gc()
  {
      return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
  }
  template<class T>void read(T &x)
  {
      rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
      while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
  }
  char sr[1<<24],z[20]; int Z,C=-1;
  template<class T>void wer(T x)
  {
      if (x<0) sr[++C]='-',x=-x;
      while (z[++Z]=x%10+48,x/=10);
      while (sr[++C]=z[Z],--Z);
  }
  IL void wer1()
  {
      sr[++C]=' ';
  }
  IL void wer2()
  {
      sr[++C]='\n';
  }
  template<class T>IL void maxa(T &x,T y) {if (x<y) x=y;} 
  template<class T>IL void mina(T &x,T y) {if (x>y) x=y;}
  template<class T>IL T MAX(T x,T y) {return x>y?x:y;}
  template<class T>IL T MIN(T x,T y) {return x<y?x:y;}
};
const int INF=1e9;
const int N=1e5+1e4;
using namespace IO;
vector<int> ve;
struct re{
    ll a[3][6],b;
};
struct sgt{
    ll f[N*4][3][6],g[N*4];
    re updata(ll x[3][6],ll y[3][6])
    {
        ll g[3][6]={},ans=0;
        ans+=x[1][0]*(y[0][1]+y[0][3]);
        ans+=x[1][1]*(y[0][0]+y[0][2]);
        ans+=x[1][2]*y[0][1];
        ans+=x[1][3]*y[0][0];
        ans+=x[1][4]*y[0][5];
        ans+=x[1][5]*y[0][4];
        g[0][0]=x[0][0]+x[2][0]*y[0][1]+x[2][1]*y[0][0];
        g[0][1]=x[0][1]+x[2][0]*y[0][0]+x[2][1]*y[0][1];
        g[0][2]=x[0][2]+x[2][0]*y[0][3]+x[2][1]*y[0][2]
        +x[2][2]*y[0][1]+x[2][3]*y[0][0];
        g[0][3]=x[0][3]+x[2][0]*y[0][2]+x[2][1]*y[0][3]
        +x[2][2]*y[0][0]+x[2][3]*y[0][1];
        g[0][4]=x[0][4]+x[2][4]*y[0][5]+x[2][5]*y[0][4];
        g[0][5]=x[0][5]+x[2][5]*y[0][5];
        g[1][0]=y[1][0]+y[2][0]*x[1][1]+y[2][1]*x[1][0];
        g[1][1]=y[1][1]+y[2][0]*x[1][0]+y[2][1]*x[1][1];
        g[1][2]=y[1][2]+y[2][0]*x[1][3]+y[2][1]*x[1][2]
        +y[2][2]*x[1][1]+y[2][3]*x[1][0];
        g[1][3]=y[1][3]+y[2][0]*x[1][2]+y[2][1]*x[1][3]
        +y[2][2]*x[1][0]+y[2][3]*x[1][1];
        g[1][4]=y[1][4]+y[2][4]*x[1][5]+y[2][5]*x[1][4];
        g[1][5]=y[1][5]+y[2][5]*x[1][5];
        g[2][0]=x[2][0]*y[2][1]+x[2][1]*y[2][0];
        g[2][1]=x[2][0]*y[2][0]+x[2][1]*y[2][1];
        g[2][2]=x[2][2]*y[2][1]+x[2][3]*y[2][0]
        +x[2][0]*y[2][3]+x[2][1]*y[2][2];
        g[2][3]=x[2][2]*y[2][0]+x[2][3]*y[2][1]
        +x[2][0]*y[2][2]+x[2][1]*y[2][3];
        g[2][4]=x[2][4]*y[2][5]+x[2][5]*y[2][4];
        g[2][5]=x[2][5]*y[2][5];
        re k;
        memcpy(k.a,g,sizeof(g)); k.b=ans;
        return k;
    }
    void change(int x,int h,int t,int pos,int k)
    {
        if (h==t)
        {
            if (k==1)
            {
                rep(i,0,2)
                {
                  f[x][i][0]=f[x][i][4]=1;
                  f[x][i][1]=f[x][i][2]=f[x][i][3]=f[x][i][5]=0;
                }
                g[x]=2;
            } else
            {
                rep(i,0,2)
                {
                    f[x][i][3]=f[x][i][5]=1;
                    f[x][i][0]=f[x][i][1]=f[x][i][2]=f[x][i][4]=0;
                }
                g[x]=0;
            }
            return;
        }
        if (pos<=mid) change(x*2,h,mid,pos,k);
        else change(x*2+1,mid+1,t,pos,k);
        re kk=updata(f[x*2],f[x*2+1]);
        memcpy(f[x],kk.a,sizeof(kk.a)); g[x]=kk.b+g[x*2]+g[x*2+1];
    }
    void query(int x,int h,int t,int h1,int t1)
    {
        if (h1<=h&&t<=t1)
        {
            ve.push_back(x); return;
        }
        if (h1<=mid) query(x*2,h,mid,h1,t1);
        if (mid<t1) query(x*2+1,mid+1,t,h1,t1);
    }
    ll query2(int x,int h,int t,int h1,int t1)
    {
        ve.clear();
        query(x,h,t,h1,t1);
        ll now[3][6],ans=0;
        for (int i=0;i<ve.size();i++) ans+=g[ve[i]];
        memcpy(now,f[ve[0]],sizeof(f[ve[0]]));
        for (int i=1;i<ve.size();i++)
        {
            re k=updata(now,f[ve[i]]);
            memcpy(now,k.a,sizeof(k.a)); ans+=k.b;
        }
        return ans;
    }
}S;
int a[N],n,m;
struct sgt2{
    int sum[N];
    IL void c(int x,int t) { for(;x<=n;x+=lowbit(x)) sum[x]+=t;};
    IL int d(int x) {int ans=0; for (;x>0;x-=lowbit(x)) ans+=sum[x]; return ans;}
    IL int q(int h,int t) {return d(t)-d(h-1);}
}S1,S2;
int main()
{
    read(n);
    rep(i,1,n) read(a[i]);
    rep(i,1,n)
    { 
      S.change(1,1,n,i,a[i]);
      if (a[i]==1) S1.c(i,1);
      if (i!=n&&a[i]^a[i+1]==1) S2.c(i,1);
    }
    read(m);
    rep(i,1,m)
    {
        int kk,x,y;
        read(kk);
        if (kk==2)
        {
            read(x); read(y);
            wer(1ll*(y-x+1)*(y-x+2)/2-(S.query2(1,1,n,x,y)-S1.q(x,y)-S2.q(x,y-1)));
            wer2();
        } else
        {
            read(x);
            if (x!=n&&a[x]^a[x+1]==1) S2.c(x,-1);
            if (a[x]==1) S1.c(x,-1);
            if (x!=1&&a[x-1]^a[x]==1) S2.c(x-1,-1);
            a[x]^=1;
            if (a[x]==1) S1.c(x,1);
            if (x!=n&&a[x]^a[x+1]==1) S2.c(x,1);
            if (x!=1&&a[x-1]^a[x]==1) S2.c(x-1,1);
            S.change(1,1,n,x,a[x]);
        }
    }
    fwrite(sr,1,C+1,stdout);
    return 0;
}

 

posted @ 2018-11-24 16:11  尹吴潇  阅读(475)  评论(0编辑  收藏  举报