[UVa 11440]Help Tomisu 数论 欧拉函数+拓欧逆元
2014-08-04 21:09
435 查看
Problem D
Help Mr. Tomisu
Input: Standard Input
Output: Standard Output
After wasting a significant time of his life in problem-setting, Mr. Tomisu is now searching for glory: A glory that will make him famous likeGoldbach and rich like Bill Gates :). And he has chosen the field of Number Theory as his prime interest. His
creator did not make him very bright and so he needs your help to solve an elementary problem, using which he will begin his pursuit for glory!
Tomisu has come to know that finding out numbers having large prime factors are very important in cryptography. Given two integers N and M,he aims to count the number of integers x between 2 and N! (factorial N), having
the property that all prime factors of x are greater than M.
Input
The input file contains at most 500 lines of inputs. Each line contains two integers N (1<N<10000001) and M (1≤M≤N and N-M≤100000). Input is terminated by a line containing two zeroes. This line should not be processed.
Problemsetter: Shahriar Manzoor
Special Thanks: Per Austrin
题目大意
求在1~N!之中,其所有质因数都大于M的数字个数。
解题思路
刚开始想到用容斥原理,处理数字中有偶数个不符合要求的质因数个数的,减去奇数个不符合要求质因数个数的。
对于每一个质因数都处理一下
TLE……
最后发现
N (1<N<10000001) and M (1≤M≤N and N-M≤100000).
500组数据,之前线性的处理方法也会直接挂
处理样例的数据发现答案是
(100!*48/210-1)mod 100000007
210 和 48 间的关系就是欧拉函数了……
换种思路,就是不超过M的所有质数的乘积P,所有数字种与P互质的个数,便是欧拉函数的典型应用了。(若不互质就拥有的小于等于M的质因数)
于是我们可以处理前k个质数的乘积,算出他们的欧拉函数(每个质数减一之积)。
就可以直接愉快的使用逆元了。
PS:由于UVa不限内存……可以直接把一些数据放在内存里咯,运行更快一些。
TLE的容斥代码:
AC代码:
Help Mr. Tomisu
Input: Standard Input
Output: Standard Output
After wasting a significant time of his life in problem-setting, Mr. Tomisu is now searching for glory: A glory that will make him famous likeGoldbach and rich like Bill Gates :). And he has chosen the field of Number Theory as his prime interest. His
creator did not make him very bright and so he needs your help to solve an elementary problem, using which he will begin his pursuit for glory!
Tomisu has come to know that finding out numbers having large prime factors are very important in cryptography. Given two integers N and M,he aims to count the number of integers x between 2 and N! (factorial N), having
the property that all prime factors of x are greater than M.
Input
The input file contains at most 500 lines of inputs. Each line contains two integers N (1<N<10000001) and M (1≤M≤N and N-M≤100000). Input is terminated by a line containing two zeroes. This line should not be processed.
Output
For each line of input produce one line of output. This line contains the value T % 100000007 (Modulo 100000007 value of T). Here T is the total number of numbers between 1 and N! (factorial N) which have prime factors greater than M.100 10 100 20 10000 9000 0 0 | 43274465 70342844 39714141 |
Special Thanks: Per Austrin
题目大意
求在1~N!之中,其所有质因数都大于M的数字个数。
解题思路
刚开始想到用容斥原理,处理数字中有偶数个不符合要求的质因数个数的,减去奇数个不符合要求质因数个数的。
对于每一个质因数都处理一下
TLE……
最后发现
N (1<N<10000001) and M (1≤M≤N and N-M≤100000).
500组数据,之前线性的处理方法也会直接挂
处理样例的数据发现答案是
(100!*48/210-1)mod 100000007
210 和 48 间的关系就是欧拉函数了……
换种思路,就是不超过M的所有质数的乘积P,所有数字种与P互质的个数,便是欧拉函数的典型应用了。(若不互质就拥有的小于等于M的质因数)
于是我们可以处理前k个质数的乘积,算出他们的欧拉函数(每个质数减一之积)。
就可以直接愉快的使用逆元了。
PS:由于UVa不限内存……可以直接把一些数据放在内存里咯,运行更快一些。
TLE的容斥代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <ctime> #include <cctype> #include <cmath> #include <string> #include <cstring> #include <stack> #include <queue> #include <list> #include <vector> #include <map> #include <set> #define sqr(x) ((x)*(x)) #define LL long long #define INF 0x3f3f3f3f #define PI acos(-1.0) #define eps 1e-10 #define mod 100000007ll using namespace std; int co[100005]; LL pri[100005],pn; void egcd(LL a,LL b,LL &x,LL &y) { if (b==0) { x=1,y=0; return ; } egcd(b,a%b,x,y); int t=x; x=y,y=t-a/b*y; } int main() { LL n,m; pn=0; for (int i=2;i<=100000;i++) { if (co[i]==0) { pri[++pn]=i; for (int j=2*i;j<=100000;j+=i) co[j]=1; } } while (~scanf("%lld%lld",&n,&m),n+m) { LL t=1; for (LL i=1;i<=n;i++) t=t*i%mod; LL preodd=0; LL preeven=t; LL ansodd,anseven; for (LL i=1;pri[i]<=m;i++) { LL x,y,di; egcd(pri[i],mod,x,y); // printf("%lld %lld \n", pri[i],i); di=(x+mod)%mod; ansodd=(preeven*di)%mod;//枚举之前的奇偶 anseven=(preodd*di)%mod; ansodd=(ansodd+preodd)%mod; anseven=(anseven+preeven)%mod; // printf("%lld \n", ansodd); // printf("%lld \n", anseven); preeven=anseven;//保存下来 preodd=ansodd; } LL ans=(-ansodd+anseven+mod-1)%mod; printf("%lld\n",ans); } return 0; }
AC代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <ctime> #include <cctype> #include <cmath> #include <string> #include <cstring> #include <stack> #include <queue> #include <list> #include <vector> #include <map> #include <set> #define sqr(x) ((x)*(x)) #define LL long long #define INF 0x3f3f3f3f #define PI acos(-1.0) #define eps 1e-10 #define mod 100000007ll using namespace std; int co[10000115]; LL pri[10000115],pn; LL fac[10000115]; LL ff[1000115]; LL fm[1000115]; void egcd(LL a,LL b,LL &x,LL &y) { if (b==0) { x=1,y=0; return ; } egcd(b,a%b,x,y); int t=x; x=y,y=t-a/b*y; } int main() { LL n,m; pn=0; for (int i=2;i<=10000107;i++) { if (co[i]==0) pri[++pn]=i; for (int j=1;(i*pri[j]<=10000107)&&(j<=pn);j++) { co[i*pri[j]]=1; if (i%pri[j]==0) break; } } fac[1]=1; for (LL i=2;i<=10000107;i++) fac[i]=(fac[i-1]*i)%mod; ff[0]=1; fm[0]=1; for (int i=1;i<=pn;i++){ fm[i]=(fm[i-1]*pri[i])%mod; ff[i]=(ff[i-1]*(pri[i]-1))%mod;}//fm[i]表示前i个质数的乘积,ff[i]表示对应的欧拉函数 while (~scanf("%lld%lld",&n,&m),n+m) { LL t=fac ; LL pt=upper_bound(pri+1,pri+pn+1,m)-pri; if (pri[pt]>=m) pt--; t=t*ff[pt]%mod; LL x,y; egcd(fm[pt],mod,x,y); x=(x+mod)%mod; t=(t*x-1+mod)%mod; printf("%lld\n",t); } return 0; }
相关文章推荐
- UVa 11440 Help Tomisu (数论欧拉函数)
- UVA 11440 Help Tomisu 数论+欧拉函数
- uva11440 Help Tomisu
- UVA 11440 Help Tomisu
- UVa 11440 Help Tomisu
- UVa11440 - Help Tomisu(数论)
- Help Tomisu UVA - 11440 难推导+欧拉函数,给定正整数N和M, 统计2和N!之间有多少个整数x满足,x的所有素因子都大于M (2<=N<=1e7, 1<=M<=N, N-M<=1E5) 输出答案除以1e8+7的余数。
- UVA 11440 Help Tomisu
- UVa 11440 Help Tomisu 欧拉函数
- 【UVA】11440 - Help Tomisu
- UVA 11426 - GCD - Extreme (II) (数论)
- 找规律(约瑟夫的数论问题,uva 1363)
- UVA 550 (暑假-数论 -B - Multiplying by Rotation)
- UVa 10892 LCM Cardinality (数论&素因子分解)
- uva 11300 - Spreading the Wealth(数论)
- uva11428(数论+二分)
- UVA 10312 - Expression Bracketing(数论+Catalan数)
- UVA305 - Joseph(数论 + 打表)
- uva 10692 - Huge Mods(数论)
- Uva 10341 Solve It(数论)