Description
【题目描述】
“伦福萨”【即" ( "】和“密西卡”【即" ) "】是两种不同的精灵咒语,已知一个成功的咒语符合如下的规定:
每一个密西卡之前都可以对应匹配到一个伦福萨,即为一个合法的精灵魔法咒语。
方便的是,我们将“伦福萨”视为" ( ",“密西卡”视为" ) ",合法的精灵魔法咒语即为一个合法的括号序列。
如:" ( ( ( ) ) ) "" ( ( ) ( ) ) "" ( ) ( ) ( ) "均为合法的魔法咒语," ) ( "" ( ) ) ( "" ( ( "均为不合法的魔法咒语。
现在弗洛莉给我一个长长的“伦福萨”【即" ( "】和“密西卡”【即" ) "】的片段,每次给我一个l和r,让我判断需要在这个片段前最少添多少个“伦福萨”【即" ( "】,以及最少添多少个“密西卡”【即" ) "】可以成为一个合法的魔法咒语,更令人不爽的是,弗洛莉有的时候还会把一个“伦福萨”【即" ( "】变成“密西卡”【即" ) "】,或把一个“密西卡”【即" ) "】变为“伦福萨”【即" ( "】。
Input
第一行两个正整数n,m,表示我现在含有的咒语元素(“伦福萨”【即" ( "】和“密西卡”【即" ) "】)的个数以及弗洛莉给我的任务个数,
第二行包含n个字符(“伦福萨”【即" ( "】或“密西卡”【即" ) "】)表示一开始弗洛莉给我的咒语片段。
以下m行包括两种任务:
Change x,表示弗洛莉将位置为x上的咒语片段进行一次变换(原来是“伦福萨”【即" ( "】变为“密西卡”【即" ) "】,原来是“密西卡”【即" ) "】变为“伦福萨”【即" ( "】)。
Query l r,询问从l到r的区间的片段,在这个片段前最少添上多少个伦福萨”【即" ( "】,在这个片段后最少添上多少个“密西卡”【即" ) "】可以成为合法的魔法序列。
Output
每个询问对应一行答案,每行包括两个整数,表示在这个片段前最少添上多少个伦福萨”【即" ( "】,在这个片段后最少添上多少个“密西卡”【即" ) "】可以成为合法的魔法序列。
Sample Input
6 4
(()()(
Query 1 3
Query 3 6
Change 6
Query 1 6
Sample Output
0 1
1 1
0 0
【样例解释】
1.片段为“ ( ( ) ”最右边填1个 ) 即可。
2.片段为“ ) ( ) ( ”最左边添1个 ( 最右边添1个 ) 即可。
3.片段为“ ( ( ) ( ) ) ”已经是合法片段。不需添加。
Data Constraint
对于20%的数据,1 ≤ n,m ≤ 100
对于40%的数据,1 ≤ n,m ≤ 3000
另外含有30%的数据,数据中不包含修改操作。
对于100%的数据,1 ≤ n,m ≤ 150,000
Summary
建立一棵线段树,记录这段区间中多余的”(“和”)“,更新一个区间时:[x表示多余的”(“,y表示多余的”)“]
- x[w]=x[w*2+1]+max(0,x[w*2]-y[w*2+1])
- y[w]=y[w*2]+max(0,y[w*2+1]-x[w*2])
code
1 var
2 l,r,h,g:array[1..2000000] of longint;
3 a:array[1..200000] of char;
4 n,m,i,j,c,v:longint;
5 ch:char;
6 procedure bb(w,x,y:longint);
7 var
8 mid:longint;
9 begin
10 l[w]:=x;
11 r[w]:=y;
12 if (x=y) then
13 begin
14 if a[x]='(' then
15 inc(h[w])
16 else inc(g[w]);
17 exit;
18 end;
19 mid:=(x+y) div 2;
20 bb(w*2,x,mid);
21 bb(w*2+1,mid+1,y);
22 if h[w*2]<g[w*2+1] then
23 begin
24 h[w]:=h[w*2+1];
25 g[w]:=g[w*2]+g[w*2+1]-h[w*2];
26 end
27 else
28 begin
29 h[w]:=h[w*2]+h[w*2+1]-g[w*2+1];
30 g[w]:=g[w*2];
31 end;
32 end;
33 procedure xw(w,x,y:longint);
34 var
35 mid:longint;
36 begin
37 mid:=(l[w]+r[w]) div 2;
38 if (l[w]=x)and(r[w]=y) then
39 begin
40 if (c<g[w]) then
41 begin
42 v:=v+g[w]-c;
43 c:=h[w];
44 end
45 else
46 c:=c+h[w]-g[w];
47 exit;
48 end;
49 if x>mid then
50 xw(w*2+1,x,y)
51 else
52 if y<=mid then
53 xw(w*2,x,y)
54 else
55 begin
56 xw(w*2,x,mid);
57 xw(w*2+1,mid+1,y);
58 end;
59 end;
60 procedure gg(w,y:longint);
61 var
62 mid:longint;
63 begin
64 mid:=(l[w]+r[w]) div 2;
65 if l[w]=r[w] then
66 begin
67 if h[w]<>0 then
68 begin
69 h[w]:=0;
70 g[w]:=1;
71 end
72 else
73 begin
74 h[w]:=1;
75 g[w]:=0;
76 end;
77 exit;
78 end;
79 if y<=mid then
80 gg(w*2,y);
81 if y>mid then
82 gg(w*2+1,y);
83 if h[w*2]<g[w*2+1] then
84 begin
85 h[w]:=h[w*2+1];
86 g[w]:=g[w*2]+g[w*2+1]-h[w*2];
87 end
88 else
89 begin
90 h[w]:=h[w*2]+h[w*2+1]-g[w*2+1];
91 g[w]:=g[w*2];
92 end;
93 end;
94 var
95 x,y:longint;
96 begin
97 assign(input,'elf.in');reset(input);
98 assign(output,'elf.out');rewrite(output);
99 readln(n,m);
100 for i:=1 to n do
101 read(a[i]);
102 readln;
103 bb(1,1,n);
104 for i:=1 to m do
105 begin
106 read(ch);
107 if ch='Q' then
108 begin
109 for j:=1 to 5 do read(ch);
110 readln(x,y);
111 c:=0;v:=0;
112 xw(1,x,y);
113 writeln(v,' ',c);
114 end;
115 if ch='C' then
116 begin
117 for j:=1 to 5 do read(ch);
118 readln(x);
119 gg(1,x);
120 end;
121 end;
122 close(input);close(output);
123 end.
View Code