2020牛客寒假算法基础集训营4C题

2020牛客寒假算法基础集训营4C题

嘻嘻我又来啦,最近补题补的有点点勤=-=
传送门
C题让我彻彻底底的明白了。。费马,您是个多么伟大的人啊(膜拜)
赛后补题参考的是zz的代码啦,不过他没有发博客,我无法转载进来
嘻嘻不过他是不会介意的=-=(ps:我最近看他的好几道题都是他都是用双指针来做的=-=,关键是我这木鱼脑袋还没有掌握到精髓qaq)

这道题他也是用双指针来写的(想来想去,我是不是帮他写了一篇博客=-=)

题目的大概意思就是说呢又是给你一个序列,让你找出一个长度为k子序列乘积最大。
我首先看到这道题脑海里面又涌现了dp(中毒了啊),跟dp最大子序列之和以及最大子序列之积差不多呀,但是在写的过程中不知道k怎么用,而且题目描述的数值也没有小于零的情况=-=(我就很迷,还是太年轻了)

双指针这么用:l是left,r是right,l和r锁定一个不包含0的长度为k的子序列,求这个乘积(记得取模),然后维护最大的乘积,之后除以最前面的一个数,慢慢的求后面的乘积(这里用乘法逆元,我栽在这里了),因为取模之后的数和原来的乘积不一样呀(而且我下午用双指针的时候,傻乎乎的每次维护完最大的答案,就把存放乘积的变量更新为1,重新求一次,不超时才怪!!)

看过zz使用双指针的代码=-=他喜欢这么用,做完某次操作,不知是何种原因退出了while循环,于是下面来一个判断,咦,不满足要求了,要退出了,于是来一个if,break掉,后面的代码跟不符合要求的子序列就无关了,于是可以放心大胆的无条件做操作(就是这里的精髓我没有掌握=-=)

乘法逆元偶要单独写出来!!!(警示!!!)

ll power(ll a, ll b)
{
	ll sum = 1;
	while (b)
	{
		if (b & 1)
		{
			sum = sum * a % mod;
		}
		a = a * a % mod;
		b >>= 1;
	}
	return sum;
}

好啦~又到了上代码的环节啦嘻嘻
开心

#include <bits/stdc++.h>
using namespace std;
#define mst(a, n) memset(a, n, sizeof(a))
typedef long long ll;
const int N = 2e5 + 10;
const ll mod = 998244353;

int n, k;
ll a[N];
ll ans;

ll power(ll a, ll b)
{
	ll sum = 1;
	while (b)
	{
		if (b & 1)
		{
			sum = sum * a % mod;
		}
		a = a * a % mod;
		b >>= 1;
	}
	return sum;
}

int main()
{
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	int l = 1, r = 1;
	ll temp = 1;
	
	while (l <= n)
	{
		while (r <= n && r - l < k)
		{
			while (!a[r] && r <= n)
			{
				temp = 1;
				l = r + 1;
				r = l;
			} 
			temp = temp * a[r] % mod;
			r++;
		}
		if (r - l < k)
		{
			break;
		}
		ans = max(ans, temp);
		temp = temp * power(a[l++], mod - 2) % mod;
	}
	cout << ans << endl;
	return 0;
}

双指针我一定要熟练!!!一定
最后发表感言:感谢zz!!!(虽然他不知情=-=)
到时间我去洗澡了=-=

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

娃娃酱斯密酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值