https://loj.ac/problem/10127
题目描述
给出一个序列(A),要求维两个操作:(①)在序列的末尾加一个数;(②)询问着个序列中最后(L)个数的最大值。
思路
这道题做法比较多,可以用动态(ST)表做,不更显然的方法是线段树。我们考虑改变一下建树操作的函数,直接把空树建出来,在正常进行插入和查询即可。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
struct Segment
{
int l,r,maxx;
}T[N<<2];
int p;
void pushup(int k)
{
T[k].maxx=max(T[k<<1].maxx,T[k<<1|1].maxx);
}
void build(int k,int l,int r)
{
T[k].l=l;T[k].r=r;
if(l==r)
{
T[k].maxx=0;
return ;
}
int mid=l+r>>1;
build(k<<1,l,mid);build(k<<1|1,mid+1,r);
pushup(k);
}
void add(int k,int x,int w)
{
if(T[k].l==x&&T[k].r==x)
{
T[k].maxx=w;
return ;
}
int mid=(T[k].l+T[k].r)>>1;
if(x<=mid)add(k<<1,x,w);
else add(k<<1|1,x,w);
pushup(k);
}
int query(int k,int l,int r)
{
if(T[k].l==l&&T[k].r==r)
return T[k].maxx;
int mid=(T[k].l+T[k].r)>>1;
if(r<=mid)return query(k<<1,l,r);
else if(l>mid)return query(k<<1|1,l,r);
else return max(query(k<<1,l,mid),query(k<<1|1,mid+1,r));
}
int read()
{
int res=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();}
return res*w;
}
void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9)write(x/10);
putchar(x%10+'0');
}
void writeln(int x)
{
write(x);
putchar('
');
}
int main()
{
int m=read();
p=read();
int cnt=0,a=0;
build(1,1,m);
while(m--)
{
char op;
scanf(" %c",&op);
if(op=='A')
{
int x=read();
add(1,++cnt,(x+a)%p);
}
else
{
int l=read();
a=query(1,cnt-l+1,cnt);
writeln(a);
}
}
return 0;
}