https://vjudge.net/problem/CodeForces-1263Eios
您要設計一個只有一行的打字機,這一行的長度是無限大,一開始能夠認爲每一個字符都是空。您的打字機有一個光標只指向一個字符,一開始指向最左側的字符。c++
使用者有三種操做:spa
L 將光標向左移一格(當光標已經在最左側時,忽略此次操做).net
R 將光標向右移一格設計
一個小寫字符或者'(',')' 將當前字符替換爲給定字符code
您須要在每次操做後,判斷這一行是不是合法括號序列(例如 (ahakioi)
就是合法的,(ige))(tscore
就是非法的),不是輸出 -1
,不然輸出最多嵌套數(例如 ()(())()()
的最多嵌套數是 2,(()(()())())(())
的最多嵌套數是 3)。blog
看上去是個大模擬,實則是個線段樹的技巧題。ci
用一個pos記錄光標的位置。get
記'('爲1,')'爲-1,其餘字符爲0,這樣若是有某個前綴和<0(只用判斷前綴和最小值<0便可),那麼就不合法,或者全部加起來不等於0,也不合法。string
單點更新,維護區間和sum,前綴和最小值mn,前綴和最大值mx。區間前綴和最小值和左右子樹有關,比較左子樹的前綴和最小值、右子樹的前綴和最小值+左子樹的區間和,用小的那個更新mn[rt],前綴和最大值同理。
那麼在合法的狀況下,前綴和的最大值即爲最多嵌套數。
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=1e6+5; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) int sum[N<<2],mn[N<<2],mx[N<<2],n; void pushUp(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; mn[rt]=min(mn[rt<<1],mn[rt<<1|1]+sum[rt<<1]); mx[rt]=max(mx[rt<<1],mx[rt<<1|1]+sum[rt<<1]); } void update(int L,int C,int l,int r,int rt) { if(l==r) { sum[rt]=mn[rt]=mx[rt]=C; return; } int m=(l+r)>>1; if(L <= m) update(L,C,l,m,rt<<1); else update(L,C,m+1,r,rt<<1|1); pushUp(rt); } int main() { std::ios::sync_with_stdio(false); cin>>n; string s; cin>>s; int pos=1,r=1,ans=0; for(int i=0; i<n; i++) { char c=s[i]; if(c=='R') pos++; else if(c=='L') { if(pos>1) pos--; } else { if(c=='(') update(pos,1,1,n,1); else if(c==')') update(pos,-1,1,n,1); else update(pos,0,1,n,1); } if(sum[1]!=0||mn[1]<0) { cout<<-1<<" "; } else cout<<mx[1]<<" "; } cout<<endl; return 0; }