zoukankan      html  css  js  c++  java
  • [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
    ",1ll*(y-x+1)*(y-x+2)/2-que(1,1,n,x,y).s);
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    Sql日期时间格式转换;取年 月 日,函数:DateName()、DATEPART()
    @@ROWCOUNT (Transact-SQL)
    C#调用存储过程简单完整例子
    C# Ajax 手机发送短信验证码 校验验证码 菜鸟级别实现方法
    C#反射技术的简单操作(读取和设置类的属性)
    .NET调用Java写的WebService
    蓝牙错误提示
    sql开启xp_cmdshell
    网页手机宽度
    对称加密算法比较
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10360836.html
Copyright © 2011-2022 走看看