有一个突发奇想的萌新
查看原帖
有一个突发奇想的萌新
515990
Editzed楼主2022/8/18 09:13

本题可不可以考虑    \ \ \ \ 在每个时间节点上操作完成后的值,

每个数,从 ii 处的 操作一 乘他,到 jj 处的 操作二 除以他,贡献区间为 [i,j1][i,j-1]

最后没被除以的,贡献区间为 [i,Q][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';
		}
	}
}
2022/8/18 09:13
加载中...