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";
}
}
}