/** 题目:Help Tomisu UVA - 11440 链接:https://vjudge.net/problem/UVA-11440 题意:给定正整数N和M, 统计2和N!之间有多少个整数x满足,x的所有素因子都大于M (2<=N<=1e7, 1<=M<=N, N-M<=1E5) 输出答案除以1e8+7的余数。 思路: lrjP338 由于x的所有素因子都>M;那么x与M!互质。 根据最大公约数的性质,对于x>y,x与y互质,那么x%y与y也互质。 由于N>=M,那么N!%M!==0; 这样只需要求出M!内与M!互质的数的个数。再乘以N!/M!即为结果。 问题的重点在于求phi(M!); 根据欧拉函数公式: phi(n) = n*(1-1/p1)*(1-1/p2)*...*(1-1/pk); 求phi(n!), 如果n为合数,那么phi(n!) = phi((n-1)!)*n; 如果n为素数,那么phi(n!) = phi((n-1)!)*n/(1-1/n) = phi((n-1)!)*(n-1); phi(1) = phi(2) = 1; 设f(i) = phi(i!); */ #include <iostream> #include <cmath> #include <cstring> #include <cstdio> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 1e7+10; const int mod = 1e8+7; int f[maxn]; int prime[maxn]; void init() { int N = sqrt(maxn+0.5); memset(prime, 0, sizeof prime); for(int i = 2; i<=N; i++){ if(prime[i]==0){ for(int j = i*i; j < maxn; j+=i){ prime[j] = 1; } } } ///prime[i]==0; is prime; f[1] = f[2] = 1; for(int i = 3; i < maxn; i++){ f[i] = 1LL*f[i-1]*(prime[i]==0?(i-1):i)%mod; } } int main() { int n, m; init(); while(scanf("%d%d",&n,&m)==2) { if(n==0&&m==0) break; ll ans = f[m]; for(int i = m+1; i <= n; i++){ ans = ans*i%mod; } printf("%lld\n",(ans-1+mod)%mod); } return 0; }
时间: 2024-10-17 18:15:49