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

猜你喜欢

转载自www.cnblogs.com/HocRiser/p/10360836.html