这下不得不向大家求助了
查看原帖
这下不得不向大家求助了
529694
Corzica楼主2023/12/4 20:36

rt,调了一晚上了,一直卡25pts,人已经疯掉了,对拍小数据出来也没问题

代码里solve处理修改,ssolve进行重构,query和qquery分别返回区间和与区间阶乘和

球球了,谢谢大佬

#include <bits/stdc++.h>
using namespace std;
int n, m, r, w, fa[100005], a[100005], ffa[320][100005], siz[100005];
int jie[10000007], inv[100005][320], sum[320], ssum[320], jjie[100005][320];
const int mod = 998244353;
inline int getl(int p) {
	return (p - 1) * r + 1;
}
inline int getr(int p) {
	return min(p * r, n);
}
inline int get_name(int p) {
	return (p - 1) / r + 1;
}
inline void ssolve(int p, int l, int rr, int x, int y) {
	for (int i = getl(p); i <= getr(p); i++) {
		if (fa[i]) {
			a[i] = a[fa[i]];
		} else {
			ffa[p][a[i]] = 0;
		}
		fa[i] = 0;
		siz[i] = 0;
	}
//	cout << p << " " << x << ' ' << y << "||";
	for (int i = l; i <= rr; i++) {
		if (a[i] == x) a[i] = y;
//		cout << a[i] << ' ';
	}
//	cout << "[]\n";
	sum[p] = 0, ssum[p] = 1;
	for (int i = getl(p); i <= getr(p); i++) {
		if (!ffa[p][a[i]]) {
			ffa[p][a[i]] = i;
			siz[i] = 1;
		} else {
			fa[i] = ffa[p][a[i]];
			siz[ffa[p][a[i]]]++;
		}
		sum[p] += a[i];
		ssum[p] = 1ll * ssum[p] * jie[a[i]] % mod;
	}
}
inline int ksm(int p, int q = mod - 2) {
	int base = 1;
	while (q) {
		if (q & 1) base = 1ll * base * p % mod;
		q >>= 1;
		p = 1ll * p * p % mod;
	}
	return base;
}
inline void solve(int p, int q, int x, int y) {
	if (get_name(p) == get_name(q)) {
		ssolve(get_name(p), p, q, x, y);
	} else if (get_name(p) == get_name(q) - 1) {
		ssolve(get_name(p), p, getr(get_name(p)), x, y);
		ssolve(get_name(q), getl(get_name(q)), q, x, y);
	} else {
		ssolve(get_name(p), p, getr(get_name(p)), x, y);
		ssolve(get_name(q), getl(get_name(q)), q, x, y);
		p = get_name(p) + 1, q = get_name(q) - 1;
		for (int i = p; i <= q; i++) {
//			cout << i << "***" << siz[ffa[i][x]] << x << "|" << y << " " << ffa[i][x] << '\n';
			if (!ffa[i][x]) continue;
			sum[i] += siz[ffa[i][x]] * (y - x);
			ssum[i] = 1ll * ssum[i] * inv[x][siz[ffa[i][x]]] % mod * 1ll * jjie[y][siz[ffa[i][x]]] % mod;
			if (!ffa[i][y]) {
				a[ffa[i][x]] = y;
				ffa[i][y] = ffa[i][x];
				ffa[i][x] = 0;
			} else {
				fa[ffa[i][x]] = ffa[i][y];
				siz[ffa[i][y]] += siz[ffa[i][x]];
				ffa[i][x] = 0;
			}
		}
	}
}
inline int query(int p, int q) {
	if (get_name(p) == get_name(q)) {
		ssolve(get_name(p), 0, -1, -1, -1);
		int ans = 0;
		for (int i = p; i <= q; i++) {
			ans += a[i];
		}
		return ans;
	} else if (get_name(p) == get_name(q) - 1) {
		ssolve(get_name(p), 0, -1, -1, -1);
		ssolve(get_name(q), 0, -1, -1, -1);
		int ans = 0;
		for (int i = p; i <= q; i++) {
			ans += a[i];
		}
		return ans;
	} else {
		int ans = query(p, getr(get_name(p))) + query(getl(get_name(q)), q);
		p = get_name(p) + 1, q = get_name(q) - 1;
		for (int i = p; i <= q; i++) {
			ans += sum[i];
		}
		return ans;
	}
}
inline int qquery(int p, int q) {
	if (get_name(p) == get_name(q)) {
		ssolve(get_name(p), 0, -1, -1, -1);
		int ans = 1;
		for (int i = p; i <= q; i++) {
			ans = 1ll * ans * jie[a[i]] % mod;
		}
		return ans;
	} else if (get_name(p) == get_name(q) - 1) {
		ssolve(get_name(p), 0, -1, -1, -1);
		ssolve(get_name(q), 0, -1, -1, -1);
		int ans = 1;
		for (int i = p; i <= q; i++) {
			ans = 1ll * ans * jie[a[i]] % mod;
		}
		return ans;
	} else {
		int ans = 1ll * qquery(p, getr(get_name(p))) * qquery(getl(get_name(q)), q) % mod;
		p = get_name(p) + 1, q = get_name(q) - 1;
		for (int i = p; i <= q; i++) {
			ans = 1ll * ans * ssum[i] % mod;
		}
		return ans;
	}
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	jie[0] = 1;
	for (int i = 1; i <= 10000000; i++) {
		jie[i] = 1ll * jie[i - 1] * i % mod;
	}
	r = sqrt(n);
	inv[100000][1] = ksm(jie[100000]);
	for (int i = 100000; i >= 0; i--) {
		if (100000 - i > 0) inv[i][1] = 1ll * inv[i + 1][1] * (i + 1) % mod;
		for (int j = 2; j <= r; j++) {
			inv[i][j] = 1ll * inv[i][j - 1] * inv[i][1] % mod;
		}
		inv[i][0] = 1;
	}
	for (int i = 100000; i >= 0; i--) {
		jjie[i][0] = 1, jjie[i][1] = jie[i];
		for (int j = 2; j <= r; j++) {
			jjie[i][j] = 1ll * jjie[i][j - 1] * jjie[i][1] % mod;
		}
	}
	w = (n % r == 0) ? (n / r) : (n / r + 1);
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 1; i <= w; i++) {
		ssum[i] = 1;
		for (int j = getl(i); j <= getr(i); j++) {
			if (!ffa[i][a[j]]) {
				ffa[i][a[j]] = j;
				siz[j] = 1;
			} else {
				fa[j] = ffa[i][a[j]];
				siz[ffa[i][a[j]]]++;
			}
			sum[i] += a[j];
			ssum[i] = 1ll * ssum[i] * jie[a[j]] % mod;
		}
	}
	int op, p, q, x, y;
	for (int i = 1; i <= m; i++) {
		cin >> op;
		if (op == 1) {
			cin >> p >> q >> x >> y;
			if (x != y && p <= q) {
				solve(p, q, x, y);
			}
		} else {
			cin >> p >> q;
			cout << 1ll * jie[query(p, q)]*ksm(qquery(p, q)) % mod << "\n";
		}
	}
}
2023/12/4 20:36
加载中...