华东交通大学2018年ACM“双基”程序设计竞赛 I

题面描述
最近,华东交通大学ACM训练基地的老阿姨被一个数学问题困扰了很久,她希望你能够帮她解决这个问题。
这个数学问题是这样的,给你一个N,要求你计算

gcd(a,b)表示a和b的最大公约数

输入描述:

多组输入,每行一个整数n(1<=n<=10^14)。

输出描述:

每行一个整数,表示答案。由于答案会很大你要对1000000007取模。
示例1

输入

复制
4
10

输出

复制
6
35

说明

样例一,2+4=6。
样例二,2+4+5+6+8+10=35。



 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <vector>
 6 #include <set>
 7 #include <map>
 8 #include <utility>
 9 #include <queue>
10 using namespace std;
11 #define ph push_back
12 const int inf =0x3f3f3f3f;
13 #define ll long long
14 using namespace std;
15 const int N = 1e5+9;
16 const ll mod = 1e9+7;
17 void  egcd(ll a,ll b,ll &x,ll &y,ll &d)
18 {
19     if(!b){
20         d=a,x=1,y=0;
21     }
22     else{
23         egcd(b,a%b,y,x,d);
24         y-=x*(a/b);
25     }
26 }
27 ll inv(ll t,ll p)
28 {
29     ll x,y,d;
30     egcd(t,p,x,y,d);
31     return d==1?(x%p+p)%p:-1;
32 }
33 ll phi(ll a){//求欧拉值
34     ll ans = a;
35     for(ll i = 2; i*i <= a; i++){
36         if(a % i == 0){
37             ans = ans / i * (i-1);
38             while(a % i == 0) a /= i;
39         }
40     }
41     if(a > 1) ans = ans / a * (a-1);
42     return ans%mod;
43 }
44 ll n;
45 int  main()
46 {
47     while(~scanf("%lld",&n)){
48         if(n==1) 
49         {
50             printf("0\n");//不然会输出500000004
51             continue;
52         }
53         ll t1=((n%mod)*((n+1)%mod)%mod*inv(2,mod))%mod;//1~n的和
54         ll t2=(n%mod)*phi(n)%mod*inv(2,mod)%mod;//一定是成对的
55         /*
56         14
57         1 13
58         3 11
59         ......
60         */
61         ll t=(((t1-t2)%mod+mod)%mod);
62         printf("%lld\n",t);
63     }
64     return 0;
65 }

猜你喜欢

转载自www.cnblogs.com/tingtin/p/9976661.html