[BZOJ5294][BJOI2018]二进制(线段树)
作者:互联网
https://www.cnblogs.com/Yuzao/p/9069527.html
合并的时候大力讨论一下即可,不是特别复杂。
1 #include<cstdio> 2 #include<algorithm> 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 4 #define ls (x<<1) 5 #define rs (ls|1) 6 #define lson ls,L,mid 7 #define rson rs,mid+1,R 8 typedef long long ll; 9 using namespace std; 10 11 const int N=100010; 12 int n,Q,op,x,y,a[N]; 13 14 struct P{ 15 ll s,dl[2][2],dr[2][2],fl[3],fr[3],l0,r0; int c0,c1; 16 void init(){ 17 rep(i,0,1) rep(j,0,1) dl[i][j]=dr[i][j]=0; 18 fl[0]=fl[1]=fr[0]=fr[1]=fl[2]=fr[2]=l0=r0=s=c0=c1=0; 19 } 20 P(){ init(); } 21 }v[N<<2]; 22 23 P merge(P a,P b){ 24 P c; 25 rep(i,0,1) rep(j,0,1){ 26 c.dl[i][j]+=a.dl[i][j]; c.dr[i][j]+=b.dr[i][j]; 27 if (i>=a.c0) c.dl[i][j]+=b.dl[i-a.c0][j^(a.c1&1)]; 28 if (i>=b.c0) c.dr[i][j]+=a.dr[i-b.c0][j^(b.c1&1)]; 29 } 30 rep(i,0,2){ 31 c.fl[i]+=a.fl[i]; c.fr[i]+=b.fr[i]; 32 if (!a.c1) c.fl[min(2,i+a.c0)]+=b.fl[i]; 33 if (!b.c1) c.fr[min(2,i+b.c0)]+=a.fr[i]; 34 } 35 if (a.c1==1 && b.l0) c.fl[min(2ll,a.c0+b.l0)]++,c.fl[2]+=b.l0-1; 36 if (b.c1==1 && a.r0) c.fr[min(2ll,b.c0+a.r0)]++,c.fr[2]+=a.r0-1; 37 c.l0=(!a.c1?a.c0+b.l0:a.l0); c.r0=(!b.c1?b.c0+a.r0:b.r0); 38 c.c0=a.c0+b.c0; c.c1=a.c1+b.c1; 39 c.s=a.s+b.s+a.dr[0][1]*(b.dl[1][0]+b.dl[0][0])+a.dr[1][0]*b.dl[0][1]; 40 c.s+=a.dr[0][0]*(b.dl[1][1]+b.dl[0][1])+a.dr[1][1]*b.dl[0][0]; 41 if (b.l0) c.s+=(a.fr[2]+a.fr[1])*b.l0,c.s+=a.fr[0]*(b.l0-1); 42 if (a.r0) c.s+=(b.fl[2]+b.fl[1])*a.r0,c.s+=b.fl[0]*(a.r0-1); 43 return c; 44 } 45 46 void put(P &t,int x){ 47 t.init(); 48 if (x) t.dl[0][1]=t.dr[0][1]=t.c1=t.s=t.fl[0]=t.fr[0]=1; 49 else t.dl[1][0]=t.dr[1][0]=t.c0=t.l0=t.r0=1; 50 } 51 52 void build(int x,int L,int R){ 53 if (L==R) { put(v[x],a[L]); return; } 54 int mid=(L+R)>>1; 55 build(lson); build(rson); v[x]=merge(v[ls],v[rs]); 56 } 57 58 void ins(int x,int L,int R,int k){ 59 if (L==R){ put(v[x],a[L]); return; } 60 int mid=(L+R)>>1; 61 if (k<=mid) ins(lson,k); else ins(rson,k); 62 v[x]=merge(v[ls],v[rs]); 63 } 64 65 P que(int x,int L,int R,int l,int r){ 66 if (L==l && r==R) return v[x]; 67 int mid=(L+R)>>1; 68 if (r<=mid) return que(lson,l,r); 69 else if (l>mid) return que(rson,l,r); 70 else return merge(que(lson,l,mid),que(rson,mid+1,r)); 71 } 72 73 int main(){ 74 freopen("binary.in","r",stdin); 75 freopen("binary.out","w",stdout); 76 scanf("%d",&n); 77 rep(i,1,n) scanf("%d",&a[i]); 78 build(1,1,n); scanf("%d",&Q); 79 while (Q--){ 80 scanf("%d%d",&op,&x); 81 if (op==1) a[x]^=1,ins(1,1,n,x); 82 else scanf("%d",&y),printf("%lld\n",1ll*(y-x+1)*(y-x+2)/2-que(1,1,n,x,y).s); 83 } 84 return 0; 85 }
标签:BJOI2018,dl,r0,int,线段,BZOJ5294,l0,c1,c0 来源: https://www.cnblogs.com/HocRiser/p/10360836.html