码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 11440 (欧拉函数) Help Tomisu

时间:2015-01-02 22:21:37      阅读:322      评论:0      收藏:0      [点我收藏+]

标签:

题意:

给出N和M,统计区间x ∈ [2, N!],x满足所有素因子都大于M的x的个数。

分析:

首先将问题转化一下,所有素因子都大于M 等价于 这个数与M!互素

对于k大于M!,k与M!互素等价于 k % M! 与 M!互素

所以我们可以求出φ(M!)(φ为欧拉函数) 然后乘以N! / M!,最后答案再减一(因为是从2开始统计的)

 

欧拉函数的公式为技术分享a

phifac[n] = φ(n!),我们递推求phifac

当n为合数时,n!和(n-1)!的素因数的集合是一样的,所以phifac[n] = n * phifac[n-1]

当n为素数是,n!中多了一个素因子n,公式中也多了一项(1 - 1/n),所以phifac[n] = n * (n-1) / n * phifac[n-1] = (n-1) * phifac[n-1]

 

技术分享
 1 #include <cstdio>
 2 #include <cmath>
 3 
 4 const int maxn = 10000000 + 10;
 5 const int MOD = 100000007;
 6 int phifac[maxn];
 7 bool vis[maxn];
 8 
 9 void sieve(int n)
10 {
11     int m = sqrt(n + 0.5);
12     for(int i = 2; i <= m; ++i) if(!vis[i])
13         for(int j = i*i; j <= n; j += i)
14             vis[j] = true;
15 }
16 
17 int main()
18 {
19     sieve(10000000);
20     phifac[1] = phifac[2] = 1;
21     for(int i = 3; i <= 10000000; ++i)
22         phifac[i] = (long long) phifac[i-1] * (vis[i] ? i : i-1) % MOD;
23 
24     int n, m;
25     while(scanf("%d%d", &n, &m) == 2)
26     {
27         if(n == 0 && m == 0) break;
28         int ans = phifac[m];
29         for(int i = m+1; i <= n; ++i) ans = (long long)ans * i % MOD;
30         printf("%d\n", (ans-1+MOD)%MOD);
31     }
32 
33     return 0;
34 }
代码君

 

UVa 11440 (欧拉函数) Help Tomisu

标签:

原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/4198825.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!