传送门:洛谷 LR-remainders | Codeforces C. LR-remainders

更佳的阅读体验:CF1932C 题解


简要题意:给定序列 $a$ 以及一个操作序列,操作前求区间 $[l, r]$ 每个元素的积,当前操作为 $\texttt{L}$ 则给左端点 $l$ 加一,为 $\texttt{R}$ 则给右端点 $r$ 减一。

需要多次求不同区间中元素的积,考虑维护区间左右端点的位置,用线段树维护区间积即可。

#include <iostream>
#define ls p << 1
#define rs p << 1 | 1
#define mid (l + r >> 1)
using namespace std;
using ll = long long;

const int N = 2e5 + 10, M = 8e5 + 10;
int t, n, l, r;
ll a[N];
string s;
struct seg_tree {
    ll s[M], m;

    void pushup(int p) {
        s[p] = s[ls] * s[rs] % m;
    }

    void build(int p, int l, int r) {
        if (l == r) return s[p] = a[l], void();
        build(ls, l, mid);
        build(rs, mid + 1, r);
        pushup(p);
    }

    ll query(int p, int l, int r, int L, int R) {
        if (l > R || r < L) return 1;
        if (l >= L && r <= R) return s[p];
        return query(ls, l, mid, L, R) * query(rs, mid + 1, r, L, R) % m;
    }
} tree;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    for (cin >> t; t; --t) {
        cin >> n >> tree.m;
        l = 1, r = n;
        for (int i = 1; i <= n; ++i) cin >> a[i], a[i] %= tree.m;
        tree.build(1, 1, n);
        cin >> s;
        for (auto p : s) {
            cout << tree.query(1, 1, n, l, r) << ' ';
            p == 'L' ? ++l : --r;
        } cout << '\n';
    } return 0;
}
最后修改:2024 年 02 月 22 日
如果觉得我的文章对你有用,请随意赞赏