线段树水题,一个节点一个节点的建,保存上一次结果,以及序列长度即可。
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;
}