题解 P8322 【『JROI-4』少女幻葬】
蓝可爱 /qq
似乎是一个复杂度略微更低的做法。
设
首先考虑
考虑枚举
直接莫反:
所以
再考虑
枚举
这部分复杂度
inline void Solve() {
for (int i = 2;i <= v;i++) {
for (int j = i;j <= v;j += i) {
if (j >= l[1] && j <= r[1]) g[mp[i][j]] = 1;
}
}
for (int i = 1;i < n;i++) {
// g->f
for (int j = 2;j <= v;j++) {
for (int k = j;k <= v;k += j) tmp[k / j] = g[mp[j][k]];
int mx = v / j;
for (int k = 1;k <= pcnt;k++) {
if (pri[k] > mx) break;
for (int x = mx / pri[k] * pri[k];x >= pri[k];x -= pri[k]) tmp[x / pri[k]] = Add(tmp[x / pri[k]], tmp[x]);
}
for (int k = 1;k <= mx;k++) tmp[k] = (tmp[k] * mu[k] % mod + mod) % mod;
for (int k = 1;k <= pcnt;k++) {
if (pri[k] > mx) break;
for (int x = pri[k];x <= mx;x += pri[k]) tmp[x] = Add(tmp[x], tmp[x / pri[k]]);
}
for (int k = j;k <= v;k += j) f[mp[j][k]] = tmp[k / j];
}
for (int j = 2;j <= v;j++) {
for (int k = j;k <= v;k += j) {
if (k < l[i + 1] || k > r[i + 1]) f[mp[j][k]] = 0;
}
}
// f->g
for (int j = 2;j <= v;j++) {
for (int k = 0;k < (1 << tpw[j]);k++) sdp[k] = 0;
for (int k = 1;k <= tpd[j];k++) {
if (d[j][k] == 1) continue;
sdp[subs[mp[d[j][k]][j]]] = Add(sdp[subs[mp[d[j][k]][j]]], f[mp[d[j][k]][j]]);
}
for (int k = 0;k < tpw[j];k++) {
for (int s = 0;s < (1 << tpw[j]);s++) {
if (s & (1 << k)) sdp[s] = Add(sdp[s], sdp[s ^ (1 << k)]);
}
}
for (int k = 1;k <= tpd[j];k++) {
if (d[j][k] == 1) continue;
g[mp[d[j][k]][j]] = sdp[((1 << tpw[j]) - 1) ^ subs[mp[d[j][k]][j]]];
}
}
}
long long ans = 0;
for (int i = 1;i <= c;i++) ans = Add(ans, f[i]);
cout << ans << endl;
}