线段树水题,一个节点一个节点的建,保存上一次结果,以及序列长度即可。
http://www.zybbs.org/JudgeOnline/problem.php?id=1012
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <string> #include <algorithm> #define MID(x,y) ( ( x + y ) >> 1 ) #define L(x) ( x << 1 ) #define R(x) ( x << 1 | 1 ) #define BUG puts("here!!!") using namespace std; const int MAX = 200010; int MOD,P; struct Tnode{ // 一维线段树 int l,r,val; long long max; int len() { return r - l;} int mid() { return MID(l,r);} bool in(int ll,int rr) { return l >= ll && r <= rr; } void lr(int ll,int rr){ l = ll; r = rr;} }; Tnode node[MAX<<2]; void init() { memset(node,0,sizeof(node)); } void Build(int t,int l,int r) { node[t].lr(l,r); if( node[t].len() == 1 ) return ; int mid = MID(l,r); Build(L(t),l,mid); Build(R(t),mid,r); } void Updata(int t,int l,int r,int val) { if( node[t].in(l,r) ) { node[t].max += val; P = node[t].max; return ; } if( node[t].len() == 1 ) return ; int mid = node[t].mid(); if( l < mid ) Updata(L(t),l,r,val); if( r > mid ) Updata(R(t),l,r,val); node[t].max = max(node[L(t)].max, node[R(t)].max); } int Query(int t,int l,int r) { if( node[t].in(l,r) ) return node[t].max; if( node[t].len() == 1 ) return 0; int mid = node[t].mid(); int ans = 0; if( l < mid ) ans = max(ans,Query(L(t),l,r)); if( r > mid ) ans = max(ans,Query(R(t),l,r)); return ans; } int main() { int m,x; char ch[5]; while( ~scanf("%d%d",&m,&MOD) ) { init(); Build(1,0,m); int t = 0,len = 0; while( m-- ) { scanf("%s%d",ch,&x); switch(ch[0]) { case 'A' :Updata(1,len,len+1,(t+x)%MOD); len++; break; case 'Q' : int ans = Query(1,len-x,len); printf("%d\n",ans); t = ans; } } } return 0; }