正题
第一题:[JSOI2008]最大数
这道题是可以用倍增维护最大值来做,每次加入一个点,维护一遍倍增数组(ST表)logn复杂度。
我也没拦着你用线段树加点。。。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
long long m,d;
long long p;
long long cnt=0;
long long st[200010][50];
long long u=0;
void change(long long x){//加入x,更新这个点的ST表
++cnt;
st[cnt][0]=x;//从当前节点数前2的0次方的最大值。
for(long long i=1;(1<<i)<=cnt;i++)
st[cnt][i]=max(st[cnt][i-1],st[cnt-(1<<(i-1))][i-1]);
}
long long finda(long long x){//找末尾到末尾-x+1的最大数
if(x==0) return 0;
long long op=log2(x);
return max(st[cnt][op],st[cnt-x+(1<<op)][op]);
}
int main(){
long long ans=0;
scanf("%lld %lld",&m,&d);
char c[2];
for(long long i=1;i<=m;i++){
scanf("%s",c);
scanf("%lld",&p);
if(c[0]=='A') change((ans+p)%d);
else{
ans=finda(p);
printf("%lld\n",ans%d);
}
}
}