Lucky Queries (线段树的区间合并)
Lucky Queries
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 7and 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
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
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):
- 47
- 74
- 74
In the second sample:
- 747
- 447
- 447
- 774
- 774
题意:n代表字符串的长度,m代表操作的次数。两种操作:count:输出该字符串中非递减子序列的最大长度(子序列不是子串,不需要连续)switch:表示将从l 到 r的所有字符改变,4变成7,7变成4
题解:
在线段树中维护一下值:
len4表示全是4的最长子序列。
len7表示全是7的最长子序列。
len47表示以4开头以7结尾的最长子序列。
对于操作2,因为反转之后对len4,len7,len47的值影响较大(主要还是len47),所以一般对这样的题都是直接维护两个值,一个是当前的,一个是反转后的,当进行反转操作时再交换就好了。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6 const int maxn=1e6+10;
7 int n,m;
8 char s[maxn];
9 char op[20];
10 struct node{
11 int l;
12 int r;
13 int laz;
14 int len4[2],len7[2],len47[2];
15 }e[maxn<<2];
16 void pushup(int cur,int c)
17 {
18 e[cur].len4[c]=e[cur<<1].len4[c]+e[cur<<1|1].len4[c];//4的长度为左子树4的长度+右子树4的长度
19 e[cur].len7[c]=e[cur<<1].len7[c]+e[cur<<1|1].len7[c];
20 int temp=e[cur<<1].len4[c]+max(e[cur<<1|1].len7[c],e[cur<<1|1].len47[c]);//len47=左子树len4+右子树len47 左子树len4+右子树len7 左子树len47+右子树len7中取较大的
21 e[cur].len47[c]=max(temp,e[cur<<1].len47[c]+e[cur<<1|1].len7[c]);
22 return;
23 }
24 void change(int cur)
25 {
26 e[cur].laz^=1;
27 swap(e[cur].len4[0],e[cur].len4[1]);
28 swap(e[cur].len7[0],e[cur].len7[1]);
29 swap(e[cur].len47[0],e[cur].len47[1]);
30 return;
31 }
32 void pushdown(int cur)
33 {
34 if(e[cur].laz)
35 {
36 //int mid=(e[cur].l+e[cur].r)/2;
37 change(cur<<1);
38 change(cur<<1|1);
39 e[cur].laz=0;
40 }
41 return;
42 }
43 void build(int l,int r,int cur)
44 {
45 e[cur].l=l;
46 e[cur].r=r;
47 e[cur].laz=0;
48 if(l==r)
49 {
50 if(s[l]=='4')
51 {
52 e[cur].len4[0]=e[cur].len7[1]=1;//e[cur].len4[0]代表没改变前len4为1,e[cur].len7[1]=1表示如果把4的值改变为7,那么len7为1 len数组中0代表没改变,1代表改变后的值
53 e[cur].len4[1]=e[cur].len7[0]=0;
54 }
55 else
56 {
57 e[cur].len7[0]=e[cur].len4[1]=1;
58 e[cur].len7[1]=e[cur].len4[0]=0;
59 }
60 e[cur].len47[0]=e[cur].len47[1]=0;
61 return;
62 }
63 int mid=(l+r)/2;
64 build(l,mid,cur<<1);
65 build(mid+1,r,cur<<1|1);
66 pushup(cur,0);
67 pushup(cur,1);
68 }
69 void update(int pl,int pr,int cur)
70 {
71 if(pl<=e[cur].l&&e[cur].r<=pr)
72 {
73 change(cur);
74 return;
75 }
76 pushdown(cur);
77 int mid=(e[cur].l+e[cur].r)/2;
78 if(pl<=mid)
79 update(pl,pr,cur<<1);
80 if(pr>mid)
81 update(pl,pr,cur<<1|1);
82 pushup(cur,0);
83 pushup(cur,1);
84 }
85 int main()
86 {
87 scanf("%d%d",&n,&m);
88 scanf("%s",s+1);
89 build(1,n,1);
90 while(m--)
91 {
92 int x,y;
93 scanf("%s",op);
94 if(op[0]=='s')
95 {
96 scanf("%d%d",&x,&y);
97 update(x,y,1);
98 }
99 else
100 {
101 printf("%d\n",max(e[1].len4[0],max(e[1].len47[0],e[1].len7[0])));
102 }
103 }
104 }