现在请求你维护一个数列(初始数列为空),要求提供以下两种操作:
1、 查询操作。
功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。
2、 插入操作。
功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。
如何每一次在末尾插入一个数并维护最大值
因为一共有\(M\)次操作,所以最多也只有可能\(M\)个数,那么当插入第\(Q\)个数时我们就把它放在第\(Q\)个位置,这样子就解决了插入操作。
查询也是很简单的,之前我们把每个数放在了末尾,现在放在了前面,所以每次只要查询从最后一个有数的位置往前\(L\)个位置,也就是\([Q-L+1,Q]\)。
这样这道题就变成了一道单点修改区间和的板子题辣~!
完整代码
#include <iostream>
using namespace std;
char ch;
int ma[8000001],ad[8000001],m,d,t,q,n;
int build(int k,int l,int r)
{
if (l==r)
{
ma[k]=0;
return 0;
}
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
int insert(int k,int l,int r,int x,int v)
{
if (l==r)return ma[k]=v;
int mid=l+r>>1;
if (x<=mid)insert(k<<1,l,mid,x,v);
else insert(k<<1|1,mid+1,r,x,v);
ma[k]=max(ma[k<<1],ma[k<<1|1]);
}
int que(int k,int l,int r,int x,int y)
{
if (l>=x&&r<=y)return ma[k];
int mid=l+r>>1,ans=0;
if (x<=mid)ans=max(ans,que(k<<1,l,mid,x,y));
if (y>mid)ans=max(ans,que(k<<1|1,mid+1,r,x,y));
ma[k]=max(ma[k<<1],ma[k<<1|1]);
return ans;
}
int main()
{
cin>>m>>d;
int a1;
n=m;
//build(1,1,n);
for (int i=1;i<=m;i++)
{
cin>>ch>>a1;
if (ch=='A')
{
q++;
insert(1,1,n,q,(a1+t)%d);
}
else
{
t=que(1,1,n,q-a1+1,q);
cout<<t<<endl;
}
}
return 0;
}
代码丑见谅qwq