题目
做法
尺取法:先用l,r记录下区间的左右端点,
1.r-l+1<k:
①:如果a[r]==0,就把l=r+1,因为l<r+1的区间乘积都是0,所以直接跳到r+1,
②:如果a[r]!=0,就把当前区间的乘积res*a[r]
2.r-l+1 ==k
①:如果a[r]==0,就把l=r+1,同理因为l<r+1的区间乘积都是0,所以直接跳到r+1,并且更新ans=max(ans,0);
②:如果a[r]!=0,就把res*a[r],在更新ans=max(ans,res);在除掉左端点的数,l++,就等效于往区间往右移动一位,注意:这里的除法要用求逆元的方式,因为每一次res%mod,所以这里要用求逆元,不能直接除
代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>
using namespace std;
#define ll long long
const ll N=2e5+5;
const ll mod=998244353;
ll a[N];
ll Qpow(ll x,ll k)//快速幂求逆元
{
ll ans = 1;
while(k)
{
if(k%2!=0) ans = ans*x%mod;
k=k>>1;
x=x*x%mod;
}
return ans;
}
int main(){
int n,k;
cin >> n >> k;
for(int i=0;i<n;i++){
cin >> a[i];
}
ll ans=-mod;
int l=0;
int r=0;
ll res=1;
for(r;r<n;r++){
if(r-l+1<k){
if(a[r]==0){
l=r+1;
ans=max(ans,(ll)0);
res=1;
}
else{
res=(res*a[r])%mod;
}
}else{
if(a[r]==0){
l=r+1;
ans=max(ans,(ll)0);
res=1;
}else{
res=res*a[r]%mod;
ans=max(ans,res);
res = res*Qpow(a[l],mod-2)%mod;
l++;
}
}
}
cout << ans;
}