[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; }