本题可不可以考虑 在每个时间节点上操作完成后的值,
每个数,从 i 处的 操作一 乘他,到 j 处的 操作二 除以他,贡献区间为 [i,j−1],
最后没被除以的,贡献区间为 [i,Q]。
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ls(x) (x)<<1
#define rs(x) ls(x)|1
#define cints const int&
#define maxn 1000000ull
int tag[maxn<<2], M, Q;
int T;
inline void pushdown(cints rt) {
(tag[ls(rt)] *= tag[rt])%=M;
(tag[rs(rt)] *= tag[rt])%=M;
tag[rt] = 1;
}
void mul(cints rt, cints ml, cints mr, cints ql, cints qr, cints val) {
if (ml == mr) return void((tag[rt] *= val) %= M);
if (ql <= ml && mr <= qr) return void((tag[rt] *= val) %= M);
pushdown(rt);
cints mid = ml + ((mr - ml) >> 1);
if (ql <= mid) mul(ls(rt), ml, mid, ql, qr, val);
if (mid < qr) mul(rs(rt), mid + 1, mr, ql, qr, val);
}
int get(cints rt, cints ml, cints mr, cints q) {
if (ml == mr) return tag[rt];
//if (ql <= ml && mr <= qr) return tag[rt];
pushdown(rt);
cints mid = ml + ((mr - ml) >> 1);
if (q <= mid) return get(ls(rt), ml, mid, q)%M;
if (mid < q) return get(rs(rt), mid + 1, mr, q)%M;
}
char opt;
int m[maxn];
bool matched[maxn];
signed main() {
ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
cin >> T;
while (T--) {
cin >> Q >> M;
fill(matched + 1, matched + maxn + 1, 0);
fill(tag + 1, tag + maxn * 4 + 1, 1);
for (int i = 1; i <= Q; ++i) {
cin >> opt;
if (opt == '1') {
cin >> m[i];
m[i] %= M;
}
else {
int pos;
cin >> pos;
matched[pos] = 1;//被除去了
mul(1, 1, Q, pos, i-1, m[pos]);//算上贡献
}
}
for (int i = 1; i <= Q; ++i) {
if (m[i] && !matched[i])/*坚持到最后,没被统计的*/ mul(1, 1, Q, i, Q, m[i]);
cout << get(1, 1, Q, i) << '\n';
}
}
}