2020牛客寒假算法基础集训营4.C——子段乘积【线段树】

题目传送门


题目描述

给出一个长度为 n 的数列 a 1 , a 2 , , a n a_1,a_2,\ldots,a_n ,求其长度为 k 的连续子段的乘积对 998244353 取模余数的最大值。


输入描述:

第一行两个整数n,k。
第二行n个整数, a 1 , a 2 , , a n a_1,a_2,\ldots,a_n


输出描述:

输出一个整数,代表最大余数。


输入

5 3
1 2 3 0 8


输出

6


说明

1 2 3 m o d    998244353 = 6 1*2*3\mod 998244353=6


备注:

1 k n 2 1 0 5 1 \le k \le n \le 2*10^5
0 a i < 998244353 0 \le a_i <998244353


题解

  • 显然暴力是超时的
  • 考虑操作很简单,就是查询最后结果,线段树维护一下就行。
  • 然后 O ( n log n ) O(n\log n) 查询一下即可

AC-Code

#include <bits/stdc++.h>
using namespace std;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
typedef long long ll;
 
const int maxn = 2e5 + 7;
const int mod = 998244353;
 
int a[maxn];
struct Node {
    int left, right;
    ll val;
};
struct Segment_Tree {
#define mid ((tree[rt].left + tree[rt].right) >> 1)
    Node tree[maxn << 2];
    void PushUp(int rt) {
        tree[rt].val = (tree[rt << 1].val * tree[rt << 1 | 1].val) % mod;
    }
    void build(int rt, int l, int r) {
        tree[rt].left = l;
        tree[rt].right = r;
        if (l == r) {
            tree[rt].val = a[l];
            return;
        }
        build(rt << 1, l, mid);
        build(rt << 1 | 1, mid + 1, r);
        PushUp(rt);
    }
    void update(int rt, int pos, int val) {
        if (tree[rt].left == tree[rt].right) {
            return;
        }
        if (pos <= mid)  update(rt << 1, pos, val);
        else    update(rt << 1 | 1, pos, val);
        PushUp(rt);
    }
    ll query(int rt, int l, int r) {
        if (l <= tree[rt].left && tree[rt].right <= r) {
            return tree[rt].val;
        }
        ll res = 1;
        if (l <= mid)    res = (res * query(rt << 1, l, r)) % mod;
        if (mid < r) res = (res * query(rt << 1|1, l, r)) % mod;
        return res;
    }
#undef mid
};
 
Segment_Tree st;
int main() {
    int n, k;   while (cin >> n >> k) {
        for (int i = 1; i <= n; ++i) cin >> a[i];
        st.build(1, 1, n);
        ll ans = 0;
        for (int i = 1; i <= n-k; ++i) {
            ans = max(ans , st.query(1, i, i + k-1));
        }
        cout << ans % mod << endl;
    }
    return 0;
}
发布了179 篇原创文章 · 获赞 109 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Q_1849805767/article/details/104269030