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表示多余的”)“]

  1. x[w]=x[w*2+1]+max(0,x[w*2]-y[w*2+1])
  2. y[w]=y[w*2]+max(0,y[w*2+1]-x[w*2])

code

Android 首页渲染时间 叶罗丽中的魔法咒语_Android 首页渲染时间

Android 首页渲染时间 叶罗丽中的魔法咒语_线段树_02

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