传送门:洛谷 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;
}