链接:https://ac.nowcoder.com/acm/contest/3005/C
来源:牛客网
题目描述
给出一个长度为 n 的数列 a1,a2,…,an,求其长度为 k 的连续子段的乘积对 998244353 取模余数的最大值。
输入描述:
第一行两个整数n,k。
第二行n个整数,a1,a2,…,an。
输出描述:
输出一个整数,代表最大余数。
示例1
输入
5 3
1 2 3 0 8
输出
6
说明
1∗2∗3mod 998244353=6
备注:
1 ≤ k ≤ n ≤ 2 ∗ 1 0 5 1\leq k\leq n\leq 2* 10^5 1≤k≤n≤2∗105
0 ≤ a i < 998244353 0≤ai<998244353 0≤ai<998244353
题解
使用尺取法求解,保持sum存的是k个数乘积的余数,但是当后移时需要将k个数中的第一个数除掉,在这里需要根据费马小定理求出乘法逆元,不能直接除。
需要注意的是,当r扫到 0的时候,直接把l直接移到0的下一位。
代码
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll mod=998244353;
ll a[200005];
ll sum=1,maxx=0;
ll power(ll a,ll b){
ll c=1;
for(;b;b>>=1){
if(b&1)
c=c*a%mod;
a=a*a%mod;
}
return c;
}
int main(){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
ll l=1,r=1;
while(r<=n){
if(a[r]){
sum=(sum*a[r])%mod;
if((r-l+1)%k==0){
maxx=max(maxx,sum);
sum=sum*power(a[l],mod-2)%mod;
l++;
}
}
else{
l=r+1;
sum=1;
}
r++;
}
cout<<maxx<<endl;
return 0;
}