HYSBZ 1012(DP)

题目链接:点击打开链接


题目大意:输入mdm表示操作个数,d表示取d的模。操作两种

一种是A,将最近查询的操作答案加上一个数字,然后对d取模,将这个数字放在数列对尾

另一种是Q,输入一个数字l,找出最后l个数字中最大的数字。

 

题目思路:看上去好像很可怕,其实....我是用了一个max1记录,每个数字对应的最大值,有一丢丢像前缀和...

 

这里详细解释一下,首先比如5 4 3 2 1,那这个按照顺序排的,l1的时候最后1个最大的数字肯定是1啊,l2的时候最后两个数字里面最大的肯定是2啊,由此类推,我们想知道最后l个数最大是多少直接输出倒数第l个数就美滋滋了,同时我们可以把这个结论扩展开,很明显可以发现,只要是一串不增序列,就能直接输出倒数第l个数为答案,非常美滋滋

问题来了,哪有这么凑巧正好给你个不增序列啊,这里给个1 2 3 4 5,那l1最后一个最大的数字是5l2照样是5l一直到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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值