【洛谷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;
}

  

posted @ 2025-02-03 00:33  elainafan  阅读(65)  评论(0)    收藏  举报