P2253 [a good solution to a problem in a drum! ]

Good question though because the segment tree water data Had a lot of violence

After doing deepened understanding of the segment tree lot

The essence of the problem is to find the longest sequence length satisfying the condition

So we use three data segment tree maintenance

int lm,rm,mm;//分别记录最左边开始的最长段 最右边开始的最长段 中间最长段 

Determining whether the right and left every time interval may be incorporated to modify the

code show as below:

#include<bits/stdc++.h>
using namespace std;//len=r-l+1
int n,m,x,a[20005];
struct SegmentTree{
    int l,r;
    int lm,rm,mm;//分别记录最左边开始的最长段 最右边开始的最长段 中间最长段 
}t[100005];
void push(int p){
    t[p].lm=t[p<<1].lm;
    //判断左区间能否与右区间合并
    if (a[t[p<<1].r]!=a[t[p<<1|1].l]&&t[p<<1].lm==(t[p<<1].r-t[p<<1].l+1)) t[p].lm+=t[p<<1|1].lm;
    t[p].rm=t[p<<1|1].rm;
    if (a[t[p<<1|1].l]!=a[t[p<<1].r]&&t[p<<1|1].rm==(t[p<<1|1].r-t[p<<1|1].l+1)) t[p].rm+=t[p<<1].rm;
    t[p].mm=max(t[p<<1].mm,t[p<<1|1].mm);
    if (a[t[p<<1].r]!=a[t[p<<1|1].l]) t[p].mm=max(t[p].mm,t[p<<1].rm+t[p<<1|1].lm);
}
void change(int p,int d){
    if (t[p].l==d&&t[p].r==d){
        a[d]^=1;
        return;
    }
    int mid=(t[p].l+t[p].r)>>1;
    if (d<=mid) change(p<<1,d);
    else change(p<<1|1,d);
    push(p);
}
void build(int p,int l,int r){
    t[p].l=l;t[p].r=r; 
    if (l==r){
        t[p].lm=1;
        t[p].mm=1;
        t[p].rm=1;
        return;
    }
    int mid=(l+r)>>1;
    build (p<<1,l,mid);
    build (p<<1|1,mid+1,r);
    push (p);
}
int main(){
    scanf("%d%d",&n,&m);
    build (1,1,n);
    for (int i=1;i<=m;i++){
        scanf("%d",&x);
        change(1,x);
        printf("%d\n",max(t[1].mm,max(t[1].lm,t[1].rm)));
    }
    return 0;
} 

Guess you like

Origin www.cnblogs.com/Hiraeth-dh/p/10961822.html