题目链接:点击打开链接
题目大意:输入m和d,m表示操作个数,d表示取d的模。操作两种
一种是A,将最近查询的操作答案加上一个数字,然后对d取模,将这个数字放在数列对尾
另一种是Q,输入一个数字l,找出最后l个数字中最大的数字。
题目思路:看上去好像很可怕,其实....我是用了一个max1记录,每个数字对应的最大值,有一丢丢像前缀和...
这里详细解释一下,首先比如5 4 3 2 1,那这个按照顺序排的,l是1的时候最后1个最大的数字肯定是1啊,l是2的时候最后两个数字里面最大的肯定是2啊,由此类推,我们想知道最后l个数最大是多少直接输出倒数第l个数就美滋滋了,同时我们可以把这个结论扩展开,很明显可以发现,只要是一串不增序列,就能直接输出倒数第l个数为答案,非常美滋滋
问题来了,哪有这么凑巧正好给你个不增序列啊,这里给个1 2 3 4 5,那l是1最后一个最大的数字是5,l是2照样是5,l一直到5一直是5(谁叫5最大呢),这个时候如果我们有一个数组5 5 5 5 5依旧可以实现上面的功能,想到了吧...没错,当有一个新的小伙伴加入这个数组的时候,先判断一下他是不是比最后一个小,如果比他大直接进来没事,如果比他小,那最后一个数字要变得跟新的小伙伴一样大,然后比较倒数第二个数字,直到有一个数字跟新的小伙伴一样大或者比他大或者全遍历完了,然后就可以很美滋滋了。
一个坑点!!!很烫!!!输入那个命令要用%s,我之前用cin>>cmd,老是说我RE,我还以为是数组越界,摸不着头脑,后来改成%s就过了,可能是没用getchar?可是我记得之前我有题直接cin很美滋滋啊,没事就这样吧,因为这个wa5次也没谁了.....
以下是代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long a[200005],max1[200005];
int main(){
int m,d,last,n;
while(~scanf("%d%d",&m,&d)){
int len=0;
last=0;
for(int i=0;i<m;i++){
char cmd;
scanf("%s%d",&cmd,&n);
if(cmd=='A'){
a[++len]=(last+n)%d;
for(int j=len;j>=1;j--){
if(a[len]>max1[j]){
max1[j]=a[len];
}
else{
break;
}
}
}
else{
printf("%lld\n",max1[len-n+1]);
last=max1[len-n+1];
}
}
}
return 0;
}