题意:求解连续长度为k的子段的最大乘积

题解:这个当时没做出来,后来队友拿双指针和逆元做出来的,这个题逆元是必须要的,逆元可以看下这个:https://www.cnblogs.com/linyujun/p/5194184.html

然后剩下的做出来的方法就多了,双指针维护区间,以及要特判0的情况

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define IOS                      \
    ios::sync_with_stdio(false); \
    cin.tie(0)

// *start on @date: 2020-02-11 14:32

ll dx[] = {0, 0, 1, -1};
ll dy[] = {1, -1, 0, 0};

const ll N = 2e5 + 5;
const ll mod = 998244353;
ll a[N];
ll sum[N];
ll n, k;
ll pow_mod(ll a, ll b, ll p)
{ //a的b次方求余p
    ll ret = 1;
    while (b)
    {
        if (b & 1)
            ret = (ret * a) % p;
        a = (a * a) % p;
        b >>= 1;
    }
    return ret;
}
ll sol(ll l, ll r)
{
    if (r - l + 1 < k)
        return 0;
    if (l > r)
        return 0;
    ll cnt = 0;
    sum[0] = 1;
    for (ll i = l; i <= r; i++)
    {
        cnt++;
        sum[cnt] = sum[cnt - 1] * a[i] % mod;
    }
    ll ans = 0;
    for (ll i = k; i <= cnt; i++)
    {
        ll t = sum[i] * pow_mod(sum[i - k], mod - 2, mod) % mod;
        ans = max(ans, t);
    }
    return ans;
}
int main()
{
    cin >> n >> k;
    ll ans = 0;
    ll cnt = 0;
    for (ll i = 1; i <= n; i++)
    {
        cin >> a[i];
        if (a[i] == 0)
        {
            ans = max(ans, sol(i - cnt, i - 1));
            cnt = 0;
        }
        else
            cnt++;
    }
    if (cnt > 0)
        ans = max(ans, sol(n - cnt + 1, n));
    cout << ans << endl;
    return 0;
}