Aizu - 1407 Parentheses Editor(对顶栈+模拟)
題目鏈接:點擊查看
題目大意:給出一個字符串,只由 ' ( ' , ' ) ' 和 ' - ' 組成,初始時給出一個空串 s,三種字符所代表的操作如下:
每次操作后問有多少個合法的括號序列,合法的括號序列如下:
題目分析:最煩寫這種題目了,需要維護很多互相有關聯的變量,訓練的時候沒插手這個題,然鵝xy哥和羊駝哥最終還是沒能調出這個惡心人的題目
考慮用失配的左括號分塊,記錄有多少個情況三的個數,用題解的圖片加以說明,比如字符串已經維護到了下面的程度:
數字代表的只是以情況 3 計數的答案,紅色的左括號是失配的左括號,將整個序列分成了互不干擾的好幾塊,接下來考慮三種操作會造成什么影響
第一種就是在末尾加上一個左括號
當前這個新的左括號將前面的字符串隔離開來,所以只需要新加上一塊,然后繼續維護即可,此時新塊中的計數歸零
第二種是在末尾加上一個右括號
考慮兩種情況,第一種情況是,這個右括號可以找到一個與之相匹配的左括號,那么在匹配之后,之前失配的左括號的這一整塊都消失掉了,并且與前面的那一塊進行了合并,造成的貢獻就是,前面的那一塊的計數加一,最終的貢獻會因為兩個區塊的合并,加上 合并后的塊的計數
再考慮另一種情況,也就是右括號無法匹配,這就說明了前面的所有左括號都得到了匹配,此時這個右括號將前后隔離開來,且此時左括號所維護的分塊個數也是為 1 ,如果在后續還有操作的話,那么只需要將左括號這僅有的這個分塊的計數歸零即可
第三種也就是刪除操作了,其實刪除操作換句話說也是一種撤銷操作,只需要將狀態恢復到上一個狀態即可,題解圖示如下:
所以我們需要在合并相鄰兩個分塊的時候額外維護一些值用于恢復,這里我選擇用用了一個對頂棧來維護分塊合并與撤銷的信息,用了一個普通的棧維護括號序列
代碼:
#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e6+100;stack<LL>st1,st2;//對頂棧維護分塊信息stack<char>st;//普通棧維護括號序列char s[N];int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);scanf("%s",s+1);int n=strlen(s+1);LL ans=0;st1.push(0);//初始時自帶一塊for(int i=1;i<=n;i++){if(s[i]=='(')//如果是左括號,額外加一個分塊{st1.push(0);st.push(s[i]);}else if(s[i]==')')//如果是右括號{if(st1.size()==1)//如果匹配失敗{st2.push(st1.top());//記錄一下需要撤銷的值st1.top()=0;//將st1唯一的塊歸零st.push('*');//打一個特殊標記}else{st2.push(st1.top());st1.pop();//相鄰兩個塊的合并st1.top()++;//倒數第二個塊的總數需要加一ans+=st1.top();//更新答案st.push(s[i]);}}else//如果是刪除操作{if(st.top()=='(')//左括號直接刪除即可{st1.pop();}else if(st.top()=='*')//如果是特殊標記的右括號,直接恢復即可,不影響答案{st1.top()=st2.top();st2.pop();}else//如果刪掉這個右括號后會影響答案,按照添加時的順序倒序更新即可{ans-=st1.top();st1.top()--;st1.push(st2.top());st2.pop();}st.pop();}printf("%lld\n",ans);}return 0; }?
總結
以上是生活随笔為你收集整理的Aizu - 1407 Parentheses Editor(对顶栈+模拟)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中石油训练赛 - One-Way Con
- 下一篇: HDU - 5514 Frogs(容斥原