Jishou University Programming Contest 2019 (to reproduce the race) -K (segment tree)

Topic link: https: //ac.nowcoder.com/acm/contest/992/K

The meaning of problems: 1e5 to a size of the array, composed of 01, there are two operations, including modifying the interval, the interval 0 over a period of 1,1 changed into 0; query interval, the number of consecutive 1 in the query section .

Thinking: Interval Query interval and modifications, obvious segment tree may be used to do, we first analyzed the complexity, the complexity of each operation logN, operating with a m times (m <= 1e5 + 1), then the total complexity is mlogn ,It works.

   What we maintain with tree line, because the required number of consecutive intervals up to 1. Then the number of required maintenance interval fr 0/1 consecutive prefix [0] / fr [1], section 0/1 suffix number BA [0] / ba [1], the maximum number of sections continuously mx 0/1 [0] / mx [1]. Maintenance because the number of continuous 0 0 and 1 can be converted to each other, a lot of time to facilitate such updates. Lazy lazy marker 1 can be exclusive or update because the update and updates not quite twice.

   Because more maintenance elements, pushup and pushdown operation on a little complicated. The way this question is to learn the query, returns the number of maximum continuous interval 1, pay attention to consider the case of the interval by the left and right sections 1 suffix prefix combinations 1.

Refer to code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn=100005;

struct node{
    int l,r,len,fr[2],ba[2],mx[2];
    int lazy;
}tr[maxn<<2];

int n,m,ans,a[maxn];

void pushup(int v){
    if(tr[v<<1].fr[0]==tr[v<<1].len){
        tr[v].fr[0]=tr[v<<1].fr[0]+tr[v<<1|1].fr[0];
        tr[v].fr[1]=0;
    }
    else if(tr[v<<1].fr[1]==tr[v<<1].len){
        tr[v].fr[1]=tr[v<<1].fr[1]+tr[v<<1|1].fr[1];
        tr[v].fr[0]=0;
    }
    else{
        tr[v].fr[0]=tr[v<<1].fr[0];
        tr[v].fr[1]=tr[v<<1].fr[1];
    }
    if(tr[v<<1|1].ba[0]==tr[v<<1|1].len){
        tr[v].ba[0]=tr[v<<1].ba[0]+tr[v<<1|1].ba[0];
        tr[v].ba[1]=0;
    }    
    else if(tr[v<<1|1] .ba [ 1 ] == tr [v << 1 | 1 ] .len) { 
        tr [the] .ba [ 1 ] = TR [i << 1 ] .ba [ 1 ] + tr [i << 1 | 1 ] .ba [ 1 ]; 
        tr [the] .ba [ 0 ] = 0 ; 
    } 
    Else { 
        tr [in] .ba [ 0 ] = tr [v << 1 | 1 ] .ba [ 0 ]; 
        tr [in] .ba [ 1 ] = tr [v << 1 | 1 ] .ba [ 1 ]; 
    } 
    Tr [in] mx [ 0]=max(tr[v<<1].ba[0]+tr[v<<1|1].fr[0],max(tr[v<<1].mx[0],tr[v<<1|1].mx[0]));
    tr[v].mx[1]=max(tr[v<<1].ba[1]+tr[v<<1|1].fr[1],max(tr[v<<1].mx[1],tr[v<<1|1].mx[1]));
}

void pushdown(int v){
    tr[v<<1].lazy^=1,tr[v<<1|1].lazy^=1;
    swap(tr[v<<1].fr[0],tr[v<<1].fr[1]);
    swap(tr[v<<1].ba[0],tr[v<<1].ba[1]);
    swap(tr[v<<1].mx[0],tr[v<<1].mx[1]);
    swap(tr[v<<1|1].fr[0],tr[v<<1|1].fr[1]);
    swap(tr[v<<1|1].ba[0],tr[v<<1|1].ba[1]);
    swap(tr[v<<1|1].mx[0],tr[v<<1|1].mx[1]);
    tr[v].lazy=0;
}

void build(int v,int l,int r){
    tr[v].l=l,tr[v].r=r,tr[v].len=r-l+1;
    if(l == r) {
         if (a [R]) { 
            tr [i] .fr [ 1 ] = 1 , tr [i] .fr [ 0 ] = 0 ; 
            tr [V], the binding [ 1 ] = 1 , tr [i] .ba [ 0 ] = 0 ; 
            tr [i] .mx [ 1 ] = 1 , tr [i] .mx [ 0 ] = 0 ; 
        } 
        Else { 
            tr [i] .fr [ 1 ] = 0 , tr [i] .fr [ 0 ] = 1 ; 
            tr [V], the binding [ 1 ] = 0,tr[v].ba[0]=1;
            tr[v].mx[1]=0,tr[v].mx[0]=1;
        }
        return;
    }
    int mid=(l+r)>>1;
    build(v<<1,l,mid);
    build(v<<1|1,mid+1,r);
    pushup(v);
}

void update(int v,int l,int r){
    if(l<=tr[v].l&&r>=tr[v].r){
        swap(tr[v].fr[0],tr[v].fr[1]);
        swap(tr[v].ba[0],tr[v].ba[1]);
        swap(tr[v].mx[0],tr[v].mx[1]);
        tr[v].lazy^=1;
        return;
    }
    if(tr[v].lazy) pushdown(v);
    int mid=(tr[v].l+tr[v].r)>>1;
    if(l<=mid) update(v<<1,l,r);
    if(r>mid) update(v<<1|1,l,r);
    pushup(v);
}

int query(int v,int l,int r){
    if(tr[v].l==l&&tr[v].r==r)
        return tr[v].mx[1];
    if(tr[v].lazy) pushdown(v);
    int mid=(tr[v].l+tr[v].r)>>1;
    if(r<=mid)
        return query(v<<1,l,r);
    else if(l>mid)
        return query(v<<1|1,l,r);
    else{
        int x,y,z;
        x=min(tr[v<<1].ba[1],mid-l+1)+min(tr[v<<1|1].fr[1],r-mid);
        y=query(v<<1,l,mid);
        z=query(v<<1|1,mid+1,r);
        return max(x,max(y,z));
    }
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d",&a[i]);
    build(1,1,n);
    scanf("%d",&m);
    while(m--){
        int op,x,y;
        scanf("%d%d%d",&op,&x,&y);
        if(op==1)
            update(1,x,y);
        else
            printf("%d\n",query(1,x,y));
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/FrankChen831X/p/11201537.html
Recommended