双向链表直接模拟。
用一个辅助数组maxSum来维护一下前k项中[1,k]的最大和。
因为光标是一格一格的移动,所以每次光标右移的时候动态更新一下即可。
时间复杂度O(n)。
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int MAXN = 1000100; const int INF = 1 << 30; struct node { int val; node *next; node *pre; }; int sum[MAXN]; int maxSum[MAXN]; int main() { //freopen( "1004.in", "r", stdin ); //freopen( "test.txt", "w", stdout ); int Q; node *head = ( node *)malloc(sizeof(node)); while ( scanf( "%d", &Q ) == 1 ) { head->pre = NULL; head->next = NULL; node *cur = head; maxSum[0] = -INF; sum[0] = 0; int pos = 0; char op[4]; int a; for ( int i = 0; i < Q; ++i ) { scanf( "%s", op ); if ( op[0] == 'I' ) { scanf( "%d", &a ); ++pos; sum[pos] = sum[pos-1] + a; maxSum[pos] = max( sum[pos], maxSum[pos-1] ); node *p = (node *)malloc( sizeof(node) ); p->val = a; p->next = NULL; p->pre = cur; if ( cur->next ) { p->next = cur->next; cur->next->pre = p; } cur->next = p; cur = cur->next; } else if ( op[0] == 'Q' ) { scanf( "%d", &a ); if ( pos < a ) a = pos; printf( "%d ", maxSum[a] ); } else if ( op[0] == 'L' ) { if ( cur->pre != NULL ) { cur = cur->pre; --pos; } } else if ( op[0] == 'R' ) { //printf( "cur->next=%d %d ", cur->next, NULL ); if ( cur->next != NULL ) { cur = cur->next; ++pos; sum[pos] = sum[pos - 1] + cur->val; maxSum[pos] = max( sum[pos], maxSum[pos-1] ); } } else if ( op[0] == 'D' ) { --pos; node *p = cur; cur = p->pre; cur->next = p->next; if ( p->next ) p->next->pre = cur; free(p); } /* node *pp = head->next; while ( pp ) { printf( "%d ", pp->val ); pp = pp->next; } puts(""); */ } } return 0; }