AT5310 [ABC162E] Sum of gcd of Tuples 题解
草,竟然不用整除分块。
不妨把题目一大堆西格玛写成这样:
然后由
然后这个就可以开始整除分块了,其实暴力也能过。
整除分块复杂度
#include <bits/stdc++.h>
#define int long long
namespace mystd {
inline int read() {
int w = 1, q = 0;
char ch = ' ';
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (ch >= '0' && ch <= '9') q = q * 10 + ch - '0', ch = getchar();
return w * q;
}
inline void write(int x) {
if (x < 0) {
x = ~(x - 1);
putchar('-');
}
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
}
using namespace std;
using namespace mystd;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 100;
int n, k, tot, pr[maxn], v[maxn], phi[maxn];
int ksm(int p, int q) {
int res = 1;
while (q) {
if (q & 1) res = res * p % mod;
p = p * p % mod, q >>= 1;
}
return res;
}
void init(int lim) {
phi[1] = 1;
for (int i = 2; i <= lim; i++) {
if (!v[i]) pr[++tot] = i, phi[i] = i - 1;
for (int j = 1; j <= tot && i * pr[j] <= lim; j++) {
v[i * pr[j]] = 1;
if (i % pr[j] == 0) {
phi[i * pr[j]] = phi[i] * pr[j];
break;
}
phi[i * pr[j]] = phi[i] * phi[pr[j]];
}
}
for (int i = 2; i <= lim; i++) phi[i] = (phi[i] + phi[i - 1]) % mod;
}
int calc(int n, int k) {
int res = 0;
for (int l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
res = (res + (phi[r] - phi[l - 1] + mod) % mod * ksm(n / l, k)) % mod;
}
return res;
}
signed main() {
k = read(), n = read();
init(1e5);
write(calc(n, k)), puts("");
return 0;
}