题目地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1012
题目大意:维护一个序列,提供查询、插入操作。
算法讨论:
线段树模板题。
可以先预置一个[1,oo]的线段树,每次插入后将len++,len作为下一次操作插入的位置。
其余操作和线段树相同。
Code:
/*
* Problem:1012
* Author:PYC
*/
#include <cstdio>
#define maxn 1000000
using namespace std;
int tree[maxn*4],lazy[maxn*4];
inline int max(int a,int b){if (a>b) return a;return b;}
inline void down(int k){
tree[k*2]+=lazy[k];
tree[k*2+1]+=lazy[k];
lazy[k*2]+=lazy[k];
lazy[k*2+1]+=lazy[k];
lazy[k]=0;
}
inline void up(int k){tree[k]=max(tree[k],max(tree[k*2],tree[k*2+1]));}
void add(int k,int lc,int rc,int p,int d){
if (lc==p && rc==p){tree[k]+=d;lazy[k]+=d;return;}
down(k);
int mid=(lc+rc)/2;
if (p<=mid) add(k*2,lc,mid,p,d);else add(k*2+1,mid+1,rc,p,d);
up(k);
}
int ask(int k,int lc,int rc,int l,int r){
if (lc==l && rc==r) return tree[k];
down(k);
int mid=(lc+rc)/2;
if (r<=mid) return ask(k*2,lc,mid,l,r);
if (l>mid) return ask(k*2+1,mid+1,rc,l,r);
return max(ask(k*2,lc,mid,l,mid),ask(k*2+1,mid+1,rc,mid+1,r));
}
int main(){
int m,d;
scanf("%d%d",&m,&d);
int len=0,t=0;
for (int i=1;i<=m;++i){
char ch;
scanf("%c",&ch);
while (ch!='A' && ch!='Q') scanf("%c",&ch);
int x;
scanf("%d",&x);
if (ch=='A'){len++;add(1,1,maxn,len,(x+t)%d);}
else{t=ask(1,1,maxn,len-x+1,len)%d;printf("%d\n",t);}
}
return 0;
}
By Chalie Pan
Feb 19,2014