HDU 4699 - Editor - [對頂棧]
阿新 • • 發佈:2018-11-02
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=4699
Problem Description
Sample Input
8
I 2
I -1
I 1
Q 3
L
D
R
Q 2
Sample Output
2
3
Hint
題意:
維護一個整數序列的編輯器,有以下五種操作,操作總數不超過 $10^6$。
$I \: x$:在當前游標位置之後插入一個整數 $x$,插入後游標移動到 $x$ 之後;
$D$:刪除游標前的一個整數;
$L$:游標左移一格;
$R$:游標右移一格;
$Q \: k$:即 $S_i$ 為前 $i$ 個整數的和,查詢 $S_1, S_2, \cdots, S_k$ 中的最大值。
題解:
已知 I,D,L,R 這四種操作都是在游標位置處發生,且操作完游標最多移動一個位置,因此可以用對頂棧的做法。
顧名思義,我們以游標為分界,分成左右兩段序列分別由兩個棧 $A,B$ 來維護,兩個棧的棧頂相對。
同時我們可以開一個 $sum$ 陣列來維護棧 $A$ 的字首和,在開一個 $mx[i]$ 陣列來儲存 $sum[1], sum[2], \cdots, sum[i]$ 中的最大值。
AC程式碼:
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+10; const int INF=0x3f3f3f3f; stack<int> A,B; int sum[maxn],mx[maxn]; void update() { int p=A.size(); sum[p]=sum[p-1]+A.top(); mx[p]=max(mx[p-1],sum[p]); } int main() { int q; while(cin>>q) { sum[0]=0; mx[0]=-INF; while(!A.empty()) A.pop();while(!B.empty()) B.pop(); while(q--) { char op[3]; int k; scanf("%s",op); switch(op[0]) { case 'I': scanf("%d",&k); A.push(k); update(); break; case 'D': A.pop(); break; case 'L': if(A.empty()) break; B.push(A.top()); A.pop(); break; case 'R': if(B.empty()) break; A.push(B.top()); B.pop(); update(); break; case 'Q': scanf("%d",&k); printf("%d\n",mx[k]); break; } } } }