1363 最小公倍数之和
Posted SJY
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1363 最小公倍数之和相关的知识,希望对你有一定的参考价值。
给出一个n,求1-n这n个数,同n的最小公倍数的和。
例如:n = 6,1,2,3,4,5,6 同6的最小公倍数分别为6,6,6,12,30,6,加在一起 = 66。
例如:n = 6,1,2,3,4,5,6 同6的最小公倍数分别为6,6,6,12,30,6,加在一起 = 66。
由于结果很大,输出Mod 1000000007的结果。
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 50000) 第2 - T + 1行:T个数A[i](A[i] <= 10^9)
Output
共T行,输出对应的最小公倍数之和
Input示例
3 5 6 9
Output示例
55 66 279
思路:欧拉函数;
最小公倍数可以表示为n*m/gcd(n,m);那么要求的就可以写为sum(i,N)= N*sum(i/gcd(N,i));我们把式子再化下就是(N/gcd(N,i))*gcd(N,i)*sum(i/gcd(N,i));
那么后面i/gcd(N,i)是与N/gcd(N,i)互质的数,那么当那么sum(i/gcd(N,i)),就是oula(N/gcd(N,i))*(N/gcd(N,i))/2;N/gcd(N,i)为N的约数,所以只要求所有N的约数,那么分解N,dfs求约数。
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<string.h> 5 #include<queue> 6 #include<math.h> 7 #include<set> 8 #include<vector> 9 #include<string.h> 10 using namespace std; 11 typedef long long LL; 12 bool prime[100010]; 13 int ans[100010]; 14 int ak[105]; 15 int cnt[105]; 16 int p; 17 int fin[100001]; 18 int oula[100010]; 19 const int mod = 1000000007; 20 void slove(LL n); 21 void dfs(int n,int m,int c,int r); 22 int quick(int n,int m); 23 int main(void) 24 { 25 int T; 26 LL n; 27 scanf("%d",&T); 28 int i,j; 29 for(i = 2; i < 1000; i++) 30 { 31 if(!prime[i]) 32 { 33 for(j = i; (i*j) <= 100005; j++) 34 { 35 prime[i*j] = true; 36 } 37 } 38 } 39 int cn = 0; 40 for(i = 2; i <= 100005 ; i++) 41 { 42 if(!prime[i]) 43 ans[cn++] = i; 44 } 45 while(T--) 46 { 47 scanf("%lld",&n); 48 slove(n); 49 } 50 return 0; 51 } 52 void slove(LL n) 53 { 54 int f = 0; 55 int c = 0; 56 int t = -1; 57 p = 0; 58 LL pp = n; 59 memset(cnt,0,sizeof(cnt)); 60 while(n > 1) 61 { 62 while(n%ans[f] == 0) 63 { 64 if(c == 0) 65 { 66 c = 1; 67 t++; 68 ak[t] = ans[f]; 69 cnt[t]++; 70 } 71 else cnt[t]++; 72 n/=ans[f]; 73 } 74 c = 0; 75 f++; 76 if(ans[f]*ans[f]>n) 77 break; 78 } 79 if(n>1) 80 { 81 t++; 82 ak[t]=n; 83 cnt[t]++; 84 } 85 dfs(0,t+1,1,1); 86 LL sum = 0; 87 int i; 88 for(i = 0; i < p; i++) 89 { 90 sum =(sum+((LL)oula[i]*(LL)fin[i]/2)%mod)%mod; 91 } 92 printf("%lld\n",(sum+1)*(LL)pp%mod); 93 } 94 void dfs(int n,int m,int c,int r) 95 { 96 if(n == m) 97 { 98 fin[p] = c; 99 oula[p++] = r; 100 return ; 101 } 102 int s = 1; 103 int i; 104 for(i = 0; i <= cnt[n]; i++) 105 { 106 if(s==1) 107 { 108 dfs(n+1,m,c*s,r); 109 } 110 else 111 { 112 dfs(n+1,m,c*s,r*s/ak[n]*(ak[n]-1)); 113 } 114 s *= ak[n]; 115 } 116 }
以上是关于1363 最小公倍数之和的主要内容,如果未能解决你的问题,请参考以下文章