双栈维护之--Hdu4699 editor

http://acm.hdu.edu.cn/showproblem.php?pid=4699

题意:简而言之,有5种操作:

I在光标右边插入一个数

D删除光标左边的数 ,

L将光标移动最左边

R将光标移动到最右边

Q k 询问k位置以前的最大前缀和

思路:定义两个栈,一个从前开始,一个从后开始,二者加起来就是整个数列。至于最大前缀和用dp维护一下就好了, dp[i]=(dp[i-1],sum[i]); sum数组里存储的是1~i的和。
注意:栈为空的情况,不能直接pop

 

#include<cstdio>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
const int inf=-0x3f3f3f3f;//注意
 
 
int sum[1000006];
int dp[1000006];//dp[i]表示在前i
 
int main(){
	int t;
	while(~scanf("%d",&t)){
		memset(sum,0,sizeof(sum));
		memset(dp,inf,sizeof(dp));//因为dp的值为最大的前缀和,维护最大需要初始化为-inf,但是memset(-inf)会有问题,所以有宏定义的修改
		stack<int>s1,s2;	
		int pos=0;//光标当前所指的位置
		while(t--){
			getchar();//注意空格
			char c;
			scanf("%c",&c);
			if(c=='I'){
				int a;
				scanf("%d",&a);
				s1.push (a);
				pos++;//移动光标都要更新一下前缀和和最大前缀和
				sum[pos]=sum[pos-1]+a;
				dp[pos]=max(dp[pos-1],sum[pos]);
			}else if(c=='Q'){
				int a;
				scanf("%d",&a);
				printf("%d\n",dp[a]);
			}else if(c=='L'){
				if(s1.empty())continue;//注意
				pos--;
				int b=s1.top ();
				s1.pop ();
				s2.push (b);
			}else if(c=='D'){
				if(s1.empty())continue;注意
				s1.pop();
				pos--;
			}else if(c=='R'){
				if(s2.empty())continue;
				int b=s2.top ();s2.pop();
				s1.push (b);
				pos++;
				sum[pos]=sum[pos-1]+b;
				dp[pos]=max(dp[pos-1],sum[pos]);
			}else{
				int a;
				scanf("%d",&a);
				printf("%d\n",dp[a]);
			}
		}
	}
}

  

 

posted @ 2020-10-06 17:27  我微笑不代表我快乐  阅读(163)  评论(0编辑  收藏  举报