计蒜客 黑白石头 统计连续子列



思路就是建两颗树 左树1 为黑树 右树0为白树 ^=来操作懒惰标记

统计左 中 右 连续子列 完成题目要求

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAX_N = 100005;
struct node {
   int len;
   int len_l;
   int len_r;
   int down;
}arr1[4*MAX_N],arr0[4*MAX_N];
void up(int p,int l,int r){
    int mid = l+(r-l)/2,len_black,len_white;
    if(arr1[p*2].len_l==(mid-l+1)){
        arr1[p].len_l = arr1[p*2+1].len_l+arr1[p*2].len_l;
    }
    else {
        arr1[p].len_l = arr1[p*2].len_l;
    }
    if(arr1[p*2+1].len_r==r-mid){
        arr1[p].len_r = arr1[p*2+1].len_r+arr1[p*2].len_r;
    }
    else {
        arr1[p].len_r = arr1[p*2+1].len_r;
    }
    len_black = arr1[p*2].len_r+arr1[p*2+1].len_l;
    arr1[p].len=max(max(max(arr1[p*2].len_l,arr1[p*2+1].len_r),max(arr1[p*2+1].len,arr1[p*2].len)),len_black);
      if(arr0[p*2].len_l==(mid-l+1)){
        arr0[p].len_l = arr0[p*2+1].len_l+arr0[p*2].len_l;
    }
    else {
        arr0[p].len_l = arr0[p*2].len_l;
    }
    if(arr0[p*2+1].len_r==r-mid){
        arr0[p].len_r = arr0[p*2+1].len_r+arr0[p*2].len_r;
    }
    else {
        arr0[p].len_r = arr0[p*2+1].len_r;
    }
    len_white = arr0[p*2].len_r+arr0[p*2+1].len_l;
    arr0[p].len=max(max(max(arr0[p*2].len_l,arr0[p*2+1].len_r),max(arr0[p*2+1].len,arr0[p*2].len)),len_white);
}
void SWAP(int p){
        int len_l = arr1[p].len_l;
        int len_r = arr1[p].len_r;
        int len_len =arr1[p].len;
        arr1[p].len_l = arr0[p].len_l;
        arr1[p].len_r = arr0[p].len_r;
        arr1[p].len = arr0[p].len;
        arr0[p].len_l = len_l;
        arr0[p].len_r = len_r;
        arr0[p].len = len_len;
}
void down(int p,int l,int r){
   if(arr1[p].down){
      arr1[p].down^=1;
      arr1[p*2].down^=1;
      arr1[p*2+1].down^=1;
      SWAP(p);
      SWAP(p*2);
      SWAP(p*2+1);
   }
}
void build(int p,int l,int r){
    if(l==r){
        scanf("%d",&arr1[p].len);
        if(arr1[p].len){
            arr1[p].len_l = 1;
            arr1[p].len_r = 1;
        }
        else {
            arr0[p].len = 1;
            arr0[p].len_l = 1;
            arr0[p].len_r = 1;
        }
        return;
    }
    down(p,l,r);
    int mid =l+(r-l)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    up(p,l,r);
}
void modify(int p,int l,int r,int x,int y){
    if(x<=l&&r<=y) {
        arr1[p].down^=1;
        SWAP(p);
        return;
    }
    int mid = l+(r-l)/2;
    down(p,l,r);
    if(x<=mid) modify(p*2,l,mid,x,y);
    if(y>mid) modify(p*2+1,mid+1,r,x,y);
    up(p,l,r);
}
node query(int p,int l,int r,int x,int y){
    if(x<=l&&r<=y){
        return arr1[p];
    }
    down(p,l,r);
    int mid = l+(r-l)/2;
    up(p,l,r);
    if(x<=mid&&y>mid){
        node nod1 = query(p*2,l,mid,x,y);
        node nod2 = query(p*2+1,mid+1,r,x,y);
        node nod;
        if(nod1.len_l==(mid-l+1)){
            nod.len_l = nod1.len_l+nod2.len_l;
        }
        else {
            nod.len_l = nod1.len_l;
        }
        if(nod2.len_r==r-mid){
            nod.len_r = nod1.len_r+nod2.len_r;
        }
        else {
             nod.len_r = nod2.len_r;
        }
        int len_len = nod1.len_r+nod2.len_l;
        nod.len=max(max(max(nod.len_r,nod.len_l),max(nod1.len,nod2.len)),len_len);
        return nod;
    }
    else if(x<=mid){
        return query(p*2,l,mid,x,y);
    }
    else if(x>mid){
        return query(p*2+1,mid+1,r,x,y);
    }
}
int main(){
    int n,m;
    scanf("%d",&n);
    build(1,1,n);
    scanf("%d",&m);
    while(m--){
        int d,a,b;
        scanf("%d%d%d",&d,&a,&b);
        if(d==1){
            modify(1,1,n,a,b);
        }
        else if(d==0) {
            printf("%d\n",query(1,1,n,a,b).len);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/heucodesong/article/details/80623586