1. 程式人生 > >華東交通大學2018年ACM“雙基”程式設計競賽 I

華東交通大學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 }