求和「Dirichlet 字首和」
阿新 • • 發佈:2020-09-17
題意及題解:%%神仙gyz,NB就完了
然後,大佬好像沒給程式碼,蒟蒻給一份。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int maxn = 1e8 + 10; inline int read() { int s = 0, w = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') w = -1; c = getchar(); } while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar(); return s * w; } int n; int prime[maxn], tot, cnt[maxn], d[maxn]; int B[maxn]; bool vis[maxn]; void Pre() { memset(vis, 0, sizeof vis); cnt[1] = 1; d[1] = 1; for (int i = 2; i <= 50000000; i++) { if (!vis[i]) { prime[++tot] = i; d[i] = 1; cnt[i] = 2; } for (int j = 1; j <= tot && i * prime[j] <= 50000000; j++) { vis[i * prime[j]] = 1; if (i % prime[j] == 0) { d[i * prime[j]] = d[i] + 1; cnt[i * prime[j]] = cnt[i] / (d[i] + 1) * (d[i] + 2); break; } d[i * prime[j]] = 1; cnt[i * prime[j]] = cnt[i] * 2; } } } int main() { //freopen("sum.in", "r", stdin); //freopen("sum.out", "w", stdout); int n = read(), p = read(); Pre(); for (int i = 1; i <= tot && prime[i] <= n; i++) { for (int j = n / prime[i]; j; j--) { cnt[j] += cnt[j * prime[i]]; } } long long ans = 0; for (int i = 1; i <= n; i++) { ans += 1LL * cnt[i] * cnt[i]; if (ans > p) ans %= p; } cout << ans << endl; return 0; }
附一些乾貨:
線性求約數個數、約數和:https://blog.csdn.net/ControlBear/article/details/77527115?utm_source=blogxgwz24
Dirichlet 字首和:https://www.cnblogs.com/yijan/p/12356665.html