#include <bits/stdc++.h>
#define For(i, l, r) for (register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for (register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Rep(i, r) for (register int i = (0), i##end = (int)(r); i < i##end; ++i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << (x) << endl
#define pb push_back
using namespace std;
template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, T b) { return b > a ? a = b, 1 : 0; }
inline int read() {
int x(0), sgn(1); char ch(getchar());
for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
return x * sgn;
}
void File() {
#ifdef zjp_shadow
freopen ("3512.in", "r", stdin);
freopen ("3512.out", "w", stdout);
#endif
}
const int Lim = 1e5, N = Lim + 1e3, Mod = 1e9 + 7;
int prime[N], pcnt, phi[N], sumphi[N], minp[N];
bitset<N> is_prime;
void Linear_Sieve(int maxn) {
is_prime.set(); is_prime[0] = is_prime[1] = false;
phi[1] = sumphi[1] = 1;
For (i, 2, maxn) {
if (is_prime[i]) prime[++ pcnt] = i, phi[i] = i - 1, minp[i] = i;
for (int j = 1, res; (res = i * prime[j]) <= maxn && j <= pcnt; ++ j) {
is_prime[res] = false; minp[res] = prime[j];
if (i % prime[j]) phi[res] = phi[i] * (prime[j] - 1);
else { phi[res] = phi[i] * prime[j]; break; }
}
sumphi[i] = (sumphi[i - 1] + phi[i]) % Mod;
}
}
map<int, int> M, val[N];
#define Out(a, b) if (a) return b;
int Phi(int n) {
Out(n <= Lim, sumphi[n]); Out(M[n], M[n]);
int res = 1ll * n * (n + 1) / 2 % Mod;
for (int i = 2, ni; i <= n; i = ni + 1)
res = (res + Mod - ((ni = n / (n / i)) - i + 1ll) * Phi(n / i)) % Mod;
return M[n] = res;
}
int S(int n, int m) {
Out(!m, 0); Out(n == 1, Phi(m)); Out(m == 1, phi[n]); Out(val[n][m], val[n][m]);
int res = 0, p = 1, q = 1, tmp = n; vector<int> fac;
while (tmp > 1) {
int x = minp[tmp]; q *= x; tmp /= x; fac.pb(x);
while (!(tmp % x)) p *= x, tmp /= x;
}
Rep (i, 1 << int(fac.size())) {
int d = 1;
Rep (j, fac.size()) if (i >> j & 1) d *= fac[j];
res = (res + 1ll * phi[q / d] * S(d, m / d)) % Mod;
}
return val[n][m] = 1ll * res * p % Mod;
}
int main () {
File();
Linear_Sieve(Lim);
int n = read(), m = read(), ans = 0;
For (i, 1, n)
ans = (ans + S(i, m)) % Mod;
printf ("%d\n", ans);
return 0;
}
13512:DZY Loves Math IV
最新推荐文章于 2024-09-13 16:27:15 发布