【洛谷P2201】数列编辑器
本题其实来自lyd老师的《算法竞赛进阶指南》
但是纸上得来终觉浅,绝知此事要躬行嘛
就把做题思路回顾在这里噜
P2201 数列编辑器
题目描述
小 Z 是一个爱好数学的小学生。最近,他在研究一些关于整数数列的性质。
为了方便他的研究,小Z希望实现一个叫做“Open Continuous Lines Processor”的数列编辑器。
一开始,数列编辑器里没有数字,只有一个光标。这个数列编辑器需要支持五种操作。
I x在当前光标前插入数字 \(x\)。D删除当前光标前的数字。L光标向前移动一个数字。R光标向后移动一个数字。Q k设光标之前的数列是 \(\{a_1,a_2,\cdots,a_n\}\),输出第 \(k\) 位及之前最大的前缀和,保证 \(k\leqslant n\)。
输入格式
第一行包含一个数字 \(N\),表示操作的个数。
接下来包含 \(N\) 行,每行包含一条命令。
输出格式
对于每个 Q k 命令,输出一个整数表示这个操作的答案。
输入输出样例 #1
输入 #1
8
I 2
I -1
I 1
Q 3
L
D
R
Q 2
输出 #1
2
3
说明/提示
数据范围
对于 \(50\%\) 的数据,\(N\leqslant1000\);
对于 \(80\%\) 的数据,\(N\leqslant10^5\);
对于 \(100\%\) 的数据,\(N\leqslant10^6\),插入的数字绝对值大小不会超过 \(1000\)。
题目保证不会在数列编辑器为空时进行 D 操作。
本题讲了一个很奇妙的方法 所谓对顶栈
什么呢?就是以光标的两端为栈顶分别开两个栈维护
然后前缀和用O(1)直接用一个数组f进行一个类似DP的操作维护
整体就是O(1)的了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
stack<int>s;
stack<int>q;
int n;
char x;
int t;
int p=0;
int presum[1000005];
int f[100005];
int main(){
f[0]=-(1<<30);
scanf("%d",&n);
for(int i=1;i<=n;i++){
cin>>x;
if(x=='I'){
scanf("%d",&t);
s.push(t);
p++;
presum[p]=presum[p-1]+t;
f[p]=max(f[p-1],presum[p]);
}
if(x=='D'){
s.pop();
p--;
}
if(x=='L'){
p--;
q.push(s.top());
s.pop();
}
if(x=='R'){
s.push(q.top());
q.pop();
p++;
presum[p]=presum[p-1]+s.top();
f[p]=max(f[p-1],presum[p]);
}
if(x=='Q'){
scanf("%d",&t);
printf("%d\n",f[t]);
}
}
system("pause");
return 0;
}

浙公网安备 33010602011771号