1. 程式人生 > 實用技巧 >20200724T2 【NOIP2015模擬10.28B組】聖章-精靈使的魔法語

20200724T2 【NOIP2015模擬10.28B組】聖章-精靈使的魔法語

Description

【背景介紹】

“魔法???算了吧,這種東西我肯定學不了的啦!”明明是個劍士,卻被眼前這位洋洋自得的精靈使——弗洛莉拖出去學魔法,真是個沒事找茬的傢伙……
“沒事啦。作為一名冒險者會發生很多情況,中毒啦,受傷啦,被咒語束縛之類的,沒有魔法就很難辦的呀!”她到是好像一副什麼都懂的樣子,真是令人火大。
“都說我是個人類了,魔法這種東西學起來很困難的吧!”我只好找個看似靠譜的藉口。
然而,她那不屈不撓的聲音又響了起來:“人類雖然與自然的共鳴,也就是魔法的連線較少,但如果認真訓練的話還是可以做到的呢!總之,試試看吧!念念咒語之類的!”弗洛莉把魔法書一把拍在了我面前。

我沒興趣地瞟了一眼,“哼。這種東西我不看也會,倫福薩——密西卡!”才剛剛唸完不知道從哪裡偷學來的魔法咒語。隨即,便聽到弗洛莉的一聲尖叫,使得整個酒店的人的視線都往這邊看來。喂喂喂,別往我這邊看啊,我有視線恐懼症啊!!!!況且,我只是把她正在吃的麵包的樣子變成蟲子而已,誰會料到這種情況啊啊啊!!
“真是的,弗洛莉才是老拖我的後腿呢!”我沒好氣地笑道……
“裡修!你……”她從牙縫裡擠出了一個字。我頓感不妙,見到了那張比魔鬼還可怕的扭曲的面孔。“真是個魔法的天才哪!”她一掃之前不愉快的表情,想我露出大拇指,好像是在誇獎我的樣子。
咦?她竟然沒有打我,那真是我福大命大。我這樣想著,便一屁股坐在了凳子上,鬆了口氣……

【題目描述】

“倫福薩”【即"("】和“密西卡”【即")"】是兩種不同的精靈咒語,已知一個成功的咒語符合如下的規定:
每一個密西卡之前都可以對應匹配到一個倫福薩,即為一個合法的精靈魔法咒語。
方便的是,我們將“倫福薩”視為"(",“密西卡”視為")",合法的精靈魔法咒語即為一個合法的括號序列。
如:"((()))""(()())""()()()"均為合法的魔法咒語,")(""())(""(("均為不合法的魔法咒語。

現在弗洛莉給我一個長長的“倫福薩”【即"("】和“密西卡”【即")"】的片段,每次給我一個l和r,讓我判斷需要在這個片段前最少添多少個“倫福薩”【即"("】,以及最少添多少個“密西卡”【即")"】可以成為一個合法的魔法咒語,更令人不爽的是,弗洛莉有的時候還會把一個“倫福薩”【即"("】變成“密西卡”【即")"】,或把一個“密西卡”【即")"】變為“倫福薩”【即"("】。

Input

第一行兩個正整數n,m,表示我現在含有的咒語元素(“倫福薩”【即"("】和“密西卡”【即")"】)的個數以及弗洛莉給我的任務個數,
第二行包含n個字元(“倫福薩”【即"("】或“密西卡”【即")"】)表示一開始弗洛莉給我的咒語片段。
以下m行包括兩種任務:
Changex,表示弗洛莉將位置為x上的咒語片段進行一次變換(原來是“倫福薩”【即"("】變為“密西卡”【即")"】,原來是“密西卡”【即")"】變為“倫福薩”【即"("】)。
Querylr,詢問從l到r的區間的片段,在這個片段前最少添上多少個倫福薩”【即"("】,在這個片段後最少添上多少個“密西卡”【即")"】可以成為合法的魔法序列。

Output

每個詢問對應一行答案,每行包括兩個整數,表示在這個片段前最少添上多少個倫福薩”【即"("】,在這個片段後最少添上多少個“密西卡”【即")"】可以成為合法的魔法序列。

Sample Input

64
(()()(
Query13
Query36
Change6
Query16

Sample Output

01
11
00
【樣例解釋】
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

solution

顯然線段樹

不過update不太好處理

所以copy zjy的

時間複雜度為O(m log n)

code

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<queue>
  7 #include<vector>
  8 #include<stack>
  9 #include<set>
 10 #include<deque>
 11 #include<map>
 12 using namespace std;
 13 
 14 template <typename T> void read(T &x) {
 15     x = 0; int f = 1; char c;
 16     for (c = getchar(); c < '0' || c > '9'; c = getchar()) if (c == '-') f = -f;
 17     for (; c >= '0' && c <= '9'; c = getchar()) x = 10 * x + c - '0' ;
 18     x *= f;
 19 }
 20 template <typename T> void write(T x){
 21     if (x < 0) putchar('-'), x = -x;
 22     if (x > 9) write(x / 10);
 23     putchar(x % 10 + '0');
 24 }
 25 template <typename T> void writeln(T x) { write(x); putchar('\n'); }
 26 template <typename T> void writesn(T x) { write(x); putchar(' '); }
 27 
 28 #define ll long long
 29 #define inf 1234567890
 30 #define next net
 31 #define P 2147483647
 32 #define N 150010
 33 #define mid ((l+r)>>1)
 34 #define lson (o<<1)
 35 #define rson (o<<1|1)
 36 #define Re register
 37 #define debug puts("zxt")
 38 
 39 int n , m , x, y;
 40 char s[N ],qwq[10];
 41 int a[N ];
 42 struct node{
 43     int left,right;
 44 }tree[N << 2], ans;
 45 node update(node a, node b)
 46 {
 47     node kkk;
 48     kkk.left = (a.left > b.right ? a.left - b.right : 0) + b.left;
 49     kkk.right = (a.left < b.right ? b.right - a.left : 0)+ a.right;
 50     return kkk;
 51 }
 52 void build(int o, int l, int r)
 53 {
 54     if(l == r)
 55     {
 56         if(a[l]) tree[o].left++;
 57         else tree[o].right++;
 58         return;
 59     }
 60     build(lson, l, mid);
 61     build(rson, mid + 1, r);
 62     tree[o] = update(tree[lson], tree[rson]);
 63     return;
 64 }
 65 void change(int o, int l, int r, int x)
 66 {
 67     if(l == r)
 68     {
 69         a[l] ^= 1;
 70         if(a[l] == 1) tree[o].left++, tree[o].right--;
 71         else tree[o].left--, tree[o].right++;
 72         return;
 73     }
 74     if(x <= mid) change(lson, l, mid, x);
 75     else change(rson, mid + 1, r, x);
 76     tree[o] = update(tree[lson], tree[rson]);
 77     return;
 78 }
 79 node query(int o, int l, int r, int L, int R )
 80 {
 81     if(l == L && R == r)
 82     {
 83         return tree[o];
 84     }
 85     if(R <= mid) return query(lson, l, mid, L, R);
 86     if(L > mid) return query(rson, mid + 1, r, L, R);
 87     return update(query(lson, l, mid, L, mid), query(rson, mid + 1, r, mid + 1, R));
 88 }
 89 signed main()
 90 {
 91     //freopen("elf.in","r",stdin);
 92     //freopen("elf.out","w",stdout);
 93     read(n); read(m );
 94     scanf("%s", s + 1);
 95     for(Re int i = 1; i <= n; i++) a[i] = (s[i] == '(' ? 1 : 0);
 96     build(1, 1, n);
 97     while(m --)
 98     {
 99         scanf("%s", qwq);
100         if(qwq[0] == 'Q')
101         {
102             read(x); read(y);
103             ans = query(1, 1, n, x, y);
104             writesn(ans.right); writeln(ans.left);
105         }
106         else
107         {
108             read(x);
109             change(1, 1, n, x);
110         }
111     }
112     return 0;
113 }