The Boss on Mars
思路
显然我们可以求得 ∑ i = 1 n i 4 = 6 n 5 + 15 n 4 + 10 n 3 − n 30 \sum_{i = 1} ^{n} i ^ 4 = \frac{6n^5 + 15n^4 + 10n ^3 - n}{30} ∑i=1ni4=306n5+15n4+10n3−n,接下来就是考虑把其中不与 n n n互质的数给踢出去了,显然我们可以考虑容斥。
假设 n = p 1 a 1 p 2 a 2 p 3 a 3 … p n − 1 a n − 1 p n a n n = p_1 ^{a_1}p_2 ^{a_2}p_3^{a_3}\dots p_{n - 1} ^{a_{n - 1}}p_n{a_n} n=p1a1p2a2p3a3…pn−1an−1pnan
假设给定一个数字 x = p 1 k 1 p 2 k 2 p 3 k 3 … p n − 1 k n − 1 p n k n x = p_1 ^{k_1}p_2 ^{k_2}p_3^{k_3}\dots p_{n - 1} ^{k_{n - 1}}p_n^{k_n} x=p1k1p2k2p3k3…pn−1kn−1pnkn我们找出 n n n中是 x x x的倍数的数字来,
可以写成 s u m = x 4 ( 1 4 + 2 4 + 3 4 + ⋯ + ( n x − 1 ) 4 + ( n x ) 4 ) sum = x ^ 4(1 ^ 4 + 2 ^ 4 + 3 ^ 4 + \dots +(\frac{n}{x} - 1) ^4 + (\frac{n}{x}) ^ 4) sum=x4(14+24+34+⋯+(xn−1)4+(xn)4),
然后再按照容斥的原则奇加,偶减,当有奇数个因子的时候加上 s u m sum sum,有偶数个因子的时候减去 s u m sum sum。
代码
/*
Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 1e4 + 10, mod = 1e9 + 7;
int prime[N], cnt;
bool st[N];
int fac[30], tot, m;
void init() {
for(int i = 2; i < N; i++) {
if(!st[i]) prime[cnt++] = i;
for(int j = 0; j < cnt && i * prime[j] < N; j++) {
st[i * prime[j]] = 1;
if(i % prime[j] == 0) break;
}
}
}
ll calc1(ll n) {
ll ans = ans = (1ll * 6 * n % mod * n % mod * n % mod * n % mod * n % mod + 1ll * 15 * n % mod * n % mod * n % mod * n % mod + 1ll * 10 * n % mod * n % mod * n % mod - n + mod) % mod;
ans = ans * 233333335 % mod;
return ans;
}
ll calc2() {
ll ans = 0;
for(int i = 1; i < (1 << tot); i++) {
int sum = 0, now = 1;
for(int j = 0; j < tot; j++) {
if(i >> j & 1) {
now *= fac[j];
sum++;
}
}
if(sum & 1) ans = (ans + calc1(m / now) * now % mod * now % mod * now % mod * now % mod) % mod;
else ans = (ans - calc1(m / now) * now % mod * now % mod * now % mod * now % mod + mod) % mod;
}
return ans;
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T; cin >> T;
init();
while(T--) {
int n;
cin >> n;
m = n;
tot = 0;
for(int i = 0; prime[i] * prime[i] <= n; i++) {
if(n % prime[i] == 0) {
fac[tot++] = prime[i];
while(n % prime[i] == 0) {
n /= prime[i];
}
}
}
if(n != 1) fac[tot++] = n;
ll ans1 = calc1(m);
ll ans2 = calc2();
cout << (ans1 - ans2 - (m == 1) + mod) % mod << endl;
}
return 0;
}