E. Lucky Queries
time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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.

Input

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.

Output

For each query count print an answer on a single line.

Examples
Input
2 3
47
count
switch 1 2
count
Output
2
1
Input
3 5
747
count
switch 1 1
count
switch 1 3
count
Output
2
3
2
Note

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):

  1. 47
  2. 74
  3. 74

In the second sample:

  1. 747
  2. 447
  3. 447
  4. 774
  5. 774

  比较好写……

 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=;
char s[maxn];
int num[maxn],Mark[maxn<<];
int M1[maxn<<],M2[maxn<<];
int M3[maxn<<],M4[maxn<<];
int tot[maxn<<],n,Q;
//M1:00 M2:11 M3:01 M4:10 void Swich(int x){
swap(M1[x],M2[x]);
swap(M3[x],M4[x]);
Mark[x]^=;
} void Push_down(int x,int l,int r){
if(!Mark[x]||l==r)return;
Swich(x<<);Swich(x<<|);
Mark[x]=;
} void Push_up(int x){
M1[x]=M1[x<<]+M1[x<<|];
M2[x]=M2[x<<]+M2[x<<|];
M3[x]=max(M1[x<<]+M2[x<<|],max(M1[x<<]+M3[x<<|],M3[x<<]+M2[x<<|]));
M4[x]=max(M2[x<<]+M1[x<<|],max(M4[x<<]+M1[x<<|],M2[x<<]+M4[x<<|]));
} void Build(int x,int l,int r){
if(l==r){
M1[x]=num[l]^;
M2[x]=num[l];
return;
}
int mid=(l+r)>>;
Build(x<<,l,mid);
Build(x<<|,mid+,r);
Push_up(x);
} void Update(int x,int l,int r,int a,int b){
Push_down(x,l,r);
if(l>=a&&r<=b){
Swich(x);
return;
}
int mid=(l+r)>>;
if(mid>=a)Update(x<<,l,mid,a,b);
if(mid<b)Update(x<<|,mid+,r,a,b);
Push_up(x);
} char op[];
int main(){
scanf("%d%d",&n,&Q);
scanf("%s",s+);
for(int i=;i<=n;i++){
num[i]=s[i]==''?:;
}
Build(,,n);
int a,b;
while(Q--){
scanf("%s",op);
if(op[]=='s'){
scanf("%d%d",&a,&b);
Update(,,n,a,b);
}
else
printf("%d\n",max(max(M1[],M2[]),M3[]));
}
return ;
}

数据结构(线段树):CodeForces 145E Lucky Queries的更多相关文章

  1. Codeforces 145E Lucky Queries 线段树

    Lucky Queries 感觉是很简单的区间合并, 但是好像我写的比较麻烦. #include<bits/stdc++.h> #define LL long long #define f ...

  2. 算法手记 之 数据结构(线段树详解)(POJ 3468)

    依然延续第一篇读书笔记,这一篇是基于<ACM/ICPC 算法训练教程>上关于线段树的讲解的总结和修改(这本书在线段树这里Error非常多),但是总体来说这本书关于具体算法的讲解和案例都是不 ...

  3. 线段树 Codeforces Round #197 (Div. 2) D. Xenia and Bit Operations

    题目传送门 /* 线段树的单点更新:有一个交叉更新,若rank=1,or:rank=0,xor 详细解释:http://www.xuebuyuan.com/1154895.html */ #inclu ...

  4. set+线段树 Codeforces Round #305 (Div. 2) D. Mike and Feet

    题目传送门 /* 题意:对于长度为x的子序列,每个序列存放为最小值,输出长度为x的子序列的最大值 set+线段树:线段树每个结点存放长度为rt的最大值,更新:先升序排序,逐个添加到set中 查找左右相 ...

  5. [线段树]Codeforces 339D Xenia and Bit Operations

    Xenia and Bit Operations time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  6. ACM/ICPC 之 数据结构-线段树+区间离散化(POJ2528)

    这道题用线段树做更方便更新和查询,但是其数据范围很大,因此要将离散化和线段树结合起来,算是一道比较经典的线段树+离散化的例题. 线段树的离散化有很多方法,在这里,我先用一次结点离散化,间接将源左右端点 ...

  7. ACM/ICPC 之 数据结构-线段树思想(POJ2182,含O(n^2)插入式解法)

    这道题在一定程度上体现了线段树的一种用法,解决的问题是:对于总计n个元素的第i个元素,已知其在[1,i]上部分序列的排名,求第i个元素在所有n个元素中的排名. 当然这道题数据比较水,所以用O(n^2) ...

  8. 模板 - 数据结构 - 线段树/SegmentTree

    区间求加法和: 单点修改的,普通线段树. struct SegmentTree { #define ls (o<<1) #define rs (o<<1|1) static c ...

  9. 第二十九篇 玩转数据结构——线段树(Segment Tree)

          1.. 线段树引入 线段树也称为区间树 为什么要使用线段树:对于某些问题,我们只关心区间(线段) 经典的线段树问题:区间染色,有一面长度为n的墙,每次选择一段墙进行染色(染色允许覆盖),问 ...

随机推荐

  1. Ubuntu上安装jdk,Jboss

    Ubuntu上安装jdk 1.使用wget命令或sft方式从oracle官方下载tar.gz格式的jdk1.7,由于ubuntu不支持rpm安装,需要转换,所以不选择rpm格式的jdk 2.使用tar ...

  2. sql 减去分钟

    SQL SERVER:SELECT DATEADD( minute,-10,GETDATE()) ORACLE:SELECT to_char(sysdate -interval '10' minute ...

  3. SQL语句优化(分享)

    一.操作符优化 1.IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格.但是用IN的SQL性能总是比较低的,从Oracle执行的步骤来分析用IN的SQL与不用 ...

  4. Android Listview with different layout for each row

    http://stackoverflow.com/questions/4777272/android-listview-with-different-layout-for-each-row 其关键在重 ...

  5. 在往oracle中插数据时,如何处理excel读取的时间空值

    //若从excel中读取的时间值为空值时,做如下转换 string YDKGSJ = string.Empty; if (dbdata.Rows[i]["约定开工时间"].ToSt ...

  6. ip接口调用

    <?php header("Content-type: text/html; charset=utf-8"); function getIP(){ if (isset($_S ...

  7. Ojbect-C2 3、NSArray和NSMutableArray数组的使用

    Adopted Protocols NSCoding encodeWithCoder: initWithCoder: NSCopying copyWithZone: NSMutableCopying ...

  8. 十二、C# 委托与Lambda表达式(匿名方法的另一种写法)

    委托与Lambda表达式   1.委托概述 2.匿名方法 3.语句Lambda 4.表达式Lambda 5.表达式树   一.委托概述 相当于C++当中的方法指针,在C#中使用delegate 委托来 ...

  9. (JavaScript实现)页面无操作倒计时退出

    项目前端页面需要实现,页面没人操作进入倒计时,以下为前端代码实现. //设置(倒计时功能)开关 var _mouseActiveListener_flag = true; beforecount:触发 ...

  10. java问题整理

    1.一个“.java”源文件中是否可以包括多个类(不是内部类)?有什么限制? 答:可以有多个类.但只能有一个public类.并且public类名必须与文件名相一致.   2.Java有没有goto? ...