Petya loves lucky numbers very much. Everybody knows that lucky numbers are positive integers whose decimal record contains only the lucky digits 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not.
Petya brought home string s with the length of n. The string only consists of lucky digits. The digits are numbered from the left to the right starting with 1. Now Petya should execute m queries of the following form:
- switch l r — "switch" digits (i.e. replace them with their opposites) at all positions with indexes from l to r, inclusive: each digit 4 is replaced with 7 and each digit 7 is replaced with 4 (1 ≤ l ≤ r ≤ n);
- count — find and print on the screen the length of the longest non-decreasing subsequence of string s.
Subsequence of a string s is a string that can be obtained from s by removing zero or more of its elements. A string is called non-decreasing if each successive digit is not less than the previous one.
Help Petya process the requests.
The first line contains two integers n and m (1 ≤ n ≤ 106, 1 ≤ m ≤ 3·105) — the length of the string s and the number of queries correspondingly. The second line contains n lucky digits without spaces — Petya's initial string. Next m lines contain queries in the form described in the statement.
For each query count print an answer on a single line.
2 3 47 count switch 1 2 count
2 1
3 5 747 count switch 1 1 count switch 1 3 count
2 3 2
In the first sample the chronology of string s after some operations are fulfilled is as follows (the sought maximum subsequence is marked with bold):
- 47
- 74
- 74
- 747
- 447
- 447
- 774
- 774
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 5000000
#define MAXN 2005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
typedef long long ll;
using namespace std;
struct Node
{
int lazy; //lazy标记
int s1; //最长不下降子序列的长度
int s2; //最长不上升子序列的长度
int num_4; //l~r之间‘4’的个数
int num_7; //l~r之间‘7’的个数
int l; //区间左端点
int r; //区间右端点
}node[maxn];
char str[maxn];
void push_down(int rt)
{
if (rt<maxn&&node[rt].lazy==1) //若lazy标记为1,表示在这部分区间的数字得翻转
{
node[rt].lazy=0; //将1置为0,表示已经翻转。
swap(node[rt].num_4,node[rt].num_7); //翻转操作将‘4’数字的个数与‘7’数字的个数互换
swap(node[rt].s1,node[rt].s2); //最长不下降子序列和最长不上升子序列互换
if (node[rt<<1].lazy==0) //若左孩子节点lazy为零则标记为1
node[rt<<1].lazy=1;
else
node[rt<<1].lazy=0; //若左孩子节点原来为1,则再加个1表示两次翻转操作,相当于不翻转,置为0
if (node[rt<<1|1].lazy==0)
node[rt<<1|1].lazy=1;
else
node[rt<<1|1].lazy=0;
}
return ;
}
void push_up(int rt)
{
push_down(rt<<1); //向上更新之前先向下更新,检查左右孩子是否有翻转操作,若有就执行翻转操作
push_down(rt<<1|1);
node[rt].s1=max(node[rt<<1].num_4+node[rt<<1|1].s1,node[rt<<1].s1+node[rt<<1|1].num_7);
node[rt].s2=max(node[rt<<1].s2+node[rt<<1|1].num_4,node[rt<<1].num_7+node[rt<<1|1].s2);
node[rt].num_4=node[rt<<1].num_4+node[rt<<1|1].num_4;
node[rt].num_7=node[rt<<1].num_7+node[rt<<1|1].num_7;
return ;
}
void build(int rt,int l,int r)
{
node[rt].l=l;
node[rt].r=r;
node[rt].lazy=0;
if (l==r) //初始化
{
char ch=str[l-1];
if (ch=='4')
{
node[rt].s1=1;
node[rt].s2=1;
node[rt].num_4=1;
node[rt].num_7=0;
}
else
{
node[rt].s1=1;
node[rt].s2=1;
node[rt].num_4=0;
node[rt].num_7=1;
}
return ;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
push_up(rt);
}
void query(int rt,int l,int r)
{
push_down(rt);
if (l<=node[rt].l&&node[rt].r<=r) //找到要翻转的区间
{
if (node[rt].lazy==1) //原先为1的置为0
node[rt].lazy=0;
else
node[rt].lazy=1; //原先为0的置为1
push_down(rt);
return ;
}
if(rt*2<maxn&&l<=node[rt<<1].r)
query(rt<<1,l,r);
if(rt*2+1<maxn&&r>=node[rt<<1|1].l)
query(rt<<1|1,l,r);
push_up(rt);
return ;
}
int main()
{
int n,m,x,y;
while(~scanf("%d%d",&n,&m))
{
char sc[10];
scanf("%s",&str);
build(1,1,n);
for(int i=1;i<=m;i++)
{
scanf("%s",sc);
if(sc[0]=='c')
printf("%d\n",node[1].s1);
else
{
scanf("%d%d",&x,&y);
query(1,x,y);
}
}
}
}