BZOJ 1012 [最大数 maxnumber]
题面
题意
维护一个初始为空的序列,有两种操作,第一种是询问序列最后 \(m\) 个数的最大值,第二种是向序列末尾添加一个数。
题解
用线段树维护区间最大值信息。
代码
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
inline int ls(int u){ return u<<1; }
inline int rs(int u){ return u<<1|1; }
const int maxm=5.5e5;
ll mod;
int l[maxm],r[maxm];
ll mxm[maxm];
char s[10];
void build(int u,int _l,int _r){
l[u]=_l; r[u]=_r; mxm[u]=0;
if (_l==_r) return;
int _m=(_l+_r)/2;
build(ls(u),_l,_m);
build(rs(u),_m+1,_r);
}
void change(int u,int p,ll val){
if (l[u]>p||r[u]<p) return;
if (l[u]==r[u]){
mxm[u]=max(mxm[u],val);
return;
}
change(ls(u),p,val);
change(rs(u),p,val);
mxm[u]=max(mxm[ls(u)],mxm[rs(u)]);
}
ll query(int u,int _l,int _r){
if (l[u]>_r||r[u]<_l) return 0;
if (l[u]>=_l&&r[u]<=_r) return mxm[u];
return max(query(ls(u),_l,_r),query(rs(u),_l,_r));
}
int main(){
int i,n,m;
ll last,x;
scanf("%d%lld",&m,&mod);
build(1,0,m);
n=0; last=0;
while (m--){
scanf("%s%lld",s,&x);
if (s[0]=='A') change(1,n++,(last+x)%mod);
else printf("%lld\n",last=query(1,n-x,n-1));
}
return 0;
}

浙公网安备 33010602011771号