hdu 4699 Editor 双栈维护最长前缀

来源:互联网 发布:h5 翻牌抽奖源码 编辑:程序博客网 时间:2024/06/11 13:10

比赛的时候第一想到的是线段树,然后就照着那个思路写了好久,到最后RE了,而且还很郁闷,我用了双向队列记录了所有增加删除和询问所在的值在线段树中的位置,然后建树维护,很荣幸的一直RE到底,到现在我都没有相处来到底是哪里错了,可能是用双链表访问越界什么的,但是到现在都找不到错误,感觉思路也没错啊!

今天上午看了解题报告,突然觉得好简单,还是接触的少了,思路不开阔,想不到好的思路。。。

思路: 用两个栈分别维护光标的前后,用数组记录光标前的栈的最大前缀和!

#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#include<stack>#include<vector>#include<climits>#include<map>using namespace std;#define rep(i,n) for(int i=0; i<n; i++)#define repf(i,n,m) for(int i=(n); i<=(m); ++i)#define repd(i,n,m) for(int i=(n); i>=(m); --i) #define ll long long#define arc(a) ((a)*(a))#define inf 100000#define exp 0.000001#define N 1000100stack<int>a,b;int n,len;int dp[N],sum[N];int main(){ char s[10];int x;   while(scanf("%d",&n)!=EOF)   {       while(!a.empty()) a.pop();   while(!b.empty()) b.pop();   memset(dp,0,sizeof(dp));   dp[0]=-INT_MAX;   memset(sum,0,sizeof(sum));   len=1;   rep(i,n)   {   scanf("%s",s);   if(s[0]=='I')   {               scanf("%d",&x);   a.push(x);   sum[len]=sum[len-1]+x;   dp[len]=max(dp[len-1],sum[len-1]+x);   len++;   }   else if(s[0]=='D')   {   if(len!=1)   {      a.pop();      len--;   }   }   else if(s[0]=='L')   {   if(len!=1)   {                   x=a.top(); a.pop();   b.push(x);   len--;   }   }   else if(s[0]=='R')   {   if(!b.empty())   {                   x=b.top(); b.pop();   a.push(x);   sum[len]=sum[len-1]+x;   dp[len]=max(dp[len-1],sum[len-1]+x);   len++;   }   }   else   {   scanf("%d",&x);   x=min(x,len-1);   if(len==1)   printf("0\n");   else      printf("%d\n",dp[x]);   }   }   }   return 0;}  



原创粉丝点击