51nod1244 欧拉函数之和 杜教筛

和上一题差不多,一个是μ*I=e,一个是φ*I=Id

稍改就得到了这题的代码

(我会告诉你我一开始逆元算错了吗)

 1 #include <bits/stdc++.h>
 2 #define MAX 5000000
 3 #define MOD 1000000007
 4 using namespace std;
 5 long long a,b,N;
 6 long long phi[MAX+1],p[MAX],ans[MAX];
 7 bool bo[MAX+1];
 8 long long work(long long n)
 9 {
10     if(n<=MAX) return phi[n];
11     if(ans[N/n]) return ans[N/n];
12     long long ret=n%MOD*(n+1)%MOD*500000004%MOD;
13     for(long long j=2;j<=n;)
14     {
15         long long nex=n/(n/j);
16         ret=(ret-(nex-j+1)%MOD*work(n/j)%MOD+MOD)%MOD;
17         j=nex+1;
18     }
19     ans[N/n]=ret;
20     return ret;
21 }
22 int main()
23 {
24     int sum=0;phi[1]=1;
25     for(int i=2;i<=MAX;i++)
26     {
27         if(!bo[i])
28             p[++sum]=i,phi[i]=i-1;
29         for(int j=1;j<=sum && p[j]*i<=MAX;j++)
30         {
31             bo[p[j]*i]=1;
32             phi[i*p[j]]=phi[i]*((i%p[j])?phi[p[j]]:p[j]);
33             if(i%p[j]==0) break;
34         }
35     }
36     for(int i=2;i<=MAX;i++)
37         phi[i]=(phi[i]+phi[i-1])%MOD;
38     scanf("%lld",&a);
39     N=a; 
40     printf("%lld\n",work(a));
41     return 0;
42 }

 

posted @ 2017-05-10 20:18  汪立超  阅读(125)  评论(0编辑  收藏