题目大意

初始是 $x=1$,我们每轮对 $x$ 做一个操作

  • 将 $x$ 变为 $k x$,并输出 $x \bmod M$。
  • 将 $x$ 变为 $x / k_i$,即取消第 $i$ 次操作,并输出 $x \bmod M$。

保证每个操作 1 的 $k$ 在操作 2 中至多被除一次。

分析

$M$ 并不保证是质数,逆元可能不存在。

可以把操作序列看作一个乘积式,初始情况下全为 $1$。

  • 操作 1 即是把第 $i$ 个数变为 $k$。
  • 操作 2 即是把第 $i$ 个数变回 $1$。

修改结束后,询问所有数的乘积。单点修改,区间查询,标准的线段树。

因为只询问全体和,zkw 好写的多。

template <class T>
struct SegmentTree {
	vector<T> tr;
	int N;

	SegmentTree(int l, int r) {
		int n = r - l + 1;
		N = 2 << std::__lg(n);
		tr.resize(N * 2 + 2, 1);
	}
	void pushdown(int i) {
		tr[i] = 1ll * tr[i * 2] * tr[i * 2 + 1] % M;
	}
	void modify(int i, T x) {
		tr[i += N] = x;
		for (i /= 2; i; i /= 2) {
			pushdown(i);
		}
	}
};

附:代码展开