SPOJ - LCMSUM / 线性筛/ 积性函数
题意简单粗暴,要我们求
按
有
可以将相同的
故答案为
积性函数可以线性筛,复杂度
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
int Gcd(int a,int b){if (b == 0) return a; return Gcd(b , a%b);}
int Lcm(int a, int b){ return a/Gcd(a,b)*b;}
template <class T>
void read(T &x) {
static char ch;
static bool neg;
for(ch = neg = 0; ch < '0' || '9' < ch; neg |= ch == '-', ch = getchar());
for(x = 0; '0' <= ch && ch <= '9'; (x *= 10) += ch - '0', ch = getchar());
x = neg ? -x : x;
}
const int maxn = 1e6 + 10;
int vis[maxn],prm[maxn],tot;
int phi[maxn];
LL ans[maxn];
void getphi(){
vis[1] = 1;
phi[1] = 1;
for(int i=2; i<maxn; i++){
if (!vis[i]){
prm[++tot] = i;
phi[i] = i-1;
}
for(int j=1; j<=tot && i * prm[j] < maxn; j++){
vis[i*prm[j]] = 1;
if (i % prm[j] == 0){
phi[i*prm[j]] = phi[i] * prm[j];
break;
}
phi[i * prm[j]] = phi[i] * (prm[j] - 1);
}
}
for(int i=1; i<maxn; i++){
for(int j=1; i*j<maxn; j++){
ans[i*j] += 1ll * j * phi[j];
}
}
for(int i=1; i<maxn; i++){
ans[i] = ans[i] * i + i;
}
}
int main(){
getphi();
int T;
read(T);
while(T--){
int n;
read(n);
printf("%lld\n",ans[n]/2);
}
return 0;
}