定义(f(n)=)选两个([0,n))的整数(a,b),且(ab)不是(n)的倍数的方案数。
求(g(n) = sum_{d|n}f(d))
(Tleq20000,nleq10^9)
解答如下:((a,b))为(gcd(a,b))
[f(n) = n^2-sum_asum_b[n|ab]\=n^2-sum_asum_b[frac{n}{(a,n)}|b]\=n^2-sum_asum_b[frac{n}{a}|b]sum_d[d=(a,n)]\=n^2-sum_asum_d[d=(a,n)]sum_b[frac{n}{d}|b]\=n^2-sum_{d|n}sum^{n/d}_{a=1}[1=(a,frac{n}{d})]sum_b[frac{n}{d}|b]\=n^2-sum_{d|n}sum^{n/d}_{a=1}[1=(a,frac{n}{d})]sum_b[frac{n}{d}|b]\=n^2-sum_{d|n}varphi(frac{n}{d})sum_b[frac{n}{d}|b]\=n^2-sum_{d|n}varphi(d)sum_b{[d|b]}\=n^2-sum_{d|n}varphi(d)frac{n}{d}\g(n)=sum_{d|n}f(d)\=sum_{d|n}d^2-sum_{d|n}sum_{k|d}varphi(k)frac{d}{k}
]
前式很简单,后式是(varphi * id * 1=id*id)
两个值均为积性函数,预处理素因子,合并答案即可
#define B cout << "BreakPoint" << endl;
#define O(x) cout << #x << " " << x << endl;
#define O_(x) cout << #x << " " << x << " ";
#define Msz(x) cout << "Sizeof " << #x << " " << sizeof(x)/1024/1024 << " MB" << endl;
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#define LL long long
const LL inf = 1e9 + 9;
const int N = 1e6 + 5;
using namespace std;
inline LL read() {
LL s = 0,w = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-')
w = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
s = s * 10 + ch - '0';
ch = getchar();
}
return s * w;
}
inline void write( LL x ) {
if( x >= 10 ) write( x / 10 );
putchar( x % 10 + '0' );
}
int T;
LL n;
int p[N],vis[N],tot;
void init() {
vis[1] = 1;
for(int i = 2; i <= 1e6; ++i) {
if(!vis[i]) p[++tot] = i;
for(int j = 1; j <= tot && p[j] * i <= 1e6; ++j) {
vis[i * p[j]] = 1;
if(i % p[j] == 0) break;
}
}
}
LL solve(LL n) {
LL ans = 1, num = 1, tn = n;
for(int i = 1; i <= tot && p[i] * p[i] <= n; ++i) if(n % p[i] == 0){
LL t = p[i], tmp1 = 1, tmp2 = 0;
while(n % t==0) {
n /= t;
tmp1 = tmp1 * t * t + 1;
++tmp2;
}
ans *= tmp1;
num *= (tmp2 + 1);
}
if(n != 1) {
num *= 2;
ans *= (1 + n * n);
}
ans -= num * tn;
return ans;
}
int main() {
T = read();
init();
while(T--) {
n = read();
write(solve(n)); putchar('
');
}
return 0;
}