Codeforces Round #104 div1 E

分析 :(这里用0,1代替4,7,写代码时节约内存空间)只有全0或全1或(全0+全1)类型的subsequence满足要求,使用线段树维护区间的四个数据,全0subsequence长度,全1长度,全0+全1长度,全1+全0长度,switch操作时交换一下数据即可 。

code :
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 4;
struct T {
    int l,r,f[2][2],lazy;
}t[maxn<<2];
char s[maxn];
void Switch(int p)
{
    int tmp=t[p].f[0][0];
    t[p].f[0][0]=t[p].f[1][1],t[p].f[1][1]=tmp;
    tmp=t[p].f[0][1];
    t[p].f[0][1]=t[p].f[1][0],t[p].f[1][0]=tmp;
}
void pushup(int p)
{
    t[p].f[0][0]=t[p*2].f[0][0]+t[p*2+1].f[0][0];
    t[p].f[1][1]=t[p*2].f[1][1]+t[p*2+1].f[1][1];
    t[p].f[0][1]=max(t[p*2].f[0][0]+max(t[p*2+1].f[0][1],t[p*2+1].f[1][1]),t[p*2].f[0][1]+t[p*2+1].f[1][1]);
    t[p].f[1][0]=max(t[p*2].f[1][1]+max(t[p*2+1].f[0][0],t[p*2+1].f[1][0]),t[p*2].f[1][0]+t[p*2+1].f[0][0]);
}
void pushdown(int p)
{
    if(t[p].lazy) {
        Switch(p*2); Switch(p*2+1);
        t[p*2].lazy=(t[p*2].lazy+t[p].lazy)%2;
        t[p*2+1].lazy=(t[p*2+1].lazy+t[p].lazy)%2;
        t[p].lazy=0;
    }
}
void build(int p,int l,int r)
{
    t[p].l=l,t[p].r=r,t[p].lazy=0;
    if(l==r) {
        if(s[l]=='1') t[p].f[1][1]=1;
        else t[p].f[0][0]=1;
        t[p].f[0][1]=t[p].f[1][0]=1;
        return;
    }
    int mid=(l+r)>>1;
    build(p*2,l,mid); build(p*2+1,mid+1,r);
    pushup(p);
}
void update(int p,int l,int r)
{
    if(l<=t[p].l&&r>=t[p].r) {
        Switch(p);
        t[p].lazy=(t[p].lazy+1)%2;//当lazy标记为奇数时才执行Switch和向下修改lazy标记,因为lazy为偶数的时候相当于switch了一次又switch回来了 
        return;
    }
    pushdown(p);
    int mid=(t[p].l+t[p].r)>>1;
    if(l<=mid) update(p*2,l,r);
    if(r>mid) update(p*2+1,l,r);
    pushup(p);
}
int main()
{
    int n,m;
    scanf("%d%d%s",&n,&m,s+1);
    for(int i=1;i<=n;i++) 
        if(s[i]=='7') s[i]='1';
        else s[i]='0';
    build(1,1,n);
    while(m--)
    {
        char op[10];
        scanf("%s",op);
        if(op[0]=='s') {
            int l,r;
            scanf("%d%d",&l,&r);
            update(1,l,r);
        }
        else printf("%d\n",max(t[1].f[0][1],max(t[1].f[0][0],t[1].f[1][1])));
    }
    return 0;
}