推一推就是
sigma d|n d*phi(n/d)
那么质因数分解 dfs出所有因数
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=100000,P=1000000007,Inv=500000004;
int prime[maxn+1],vst[maxn+5],tot;
inline void Init(){
for (int i=2;i<=maxn;i++){
if (!vst[i]) prime[++tot]=i;
for (int j=1;(ll)prime[j]*i<=maxn && j<=tot;j++){
vst[i*prime[j]]=1;
if (i%prime[j]==0) break;
}
}
}
int n; ll Ans;
int pri[25],q[25],len;
void dfs(int t,int cur,int phi){
if(t==len+1) {
(Ans+=cur*phi%P)%P;
return;
}
dfs(t+1,cur,phi);
for (int i=1;i<q[t];i++)
dfs(t+1,cur*=pri[t],phi/=pri[t]);
dfs(t+1,cur*=pri[t],phi/=(pri[t]-1));
}
inline void Mac(int n){
int tem=n; len=0; int phi=n;
for (int i=1;i<=tot && (ll)prime[i]*prime[i]<=tem;i++)
if (tem%prime[i]==0){
pri[++len]=prime[i]; q[len]=0; phi=phi/pri[len]*(pri[len]-1);
while (tem%prime[i]==0) tem/=prime[i],q[len]++;
}
if (tem!=1) pri[++len]=tem,q[len]=1,phi=phi/pri[len]*(pri[len]-1);
dfs(1,1,phi);
}
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d",&n); Init();
Ans=0;
Mac(n);
printf("%lld\n",Ans);
return 0;
}