Co-prime
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1372 Accepted Submission(s): 514
Problem Description
Given a number N, you are asked to count the number of integers between A and B inclusive which are relatively prime to N.
Two integers are said to be co-prime or relatively prime if they have no common positive divisors other than 1 or, equivalently, if their greatest common divisor is 1. The number 1 is relatively prime to every integer.
Two integers are said to be co-prime or relatively prime if they have no common positive divisors other than 1 or, equivalently, if their greatest common divisor is 1. The number 1 is relatively prime to every integer.
Input
The first line on input contains T (0 < T <= 100) the number of test cases, each of the next T lines contains three integers A, B, N where (1 <= A <= B <= 10
15) and (1 <=N <= 10
9).
Output
For each test case, print the number of integers between A and B inclusive which are relatively prime to N. Follow the output format below.
Sample Input
2 1 10 2 3 15 5
Sample Output
Case #1: 5 Case #2: 10/* 题目大意:求1--n中与m互质的个数 终于搞定了,之前搞懂,又看了好长时间, Time:2014-8-19 19:27 */ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAX=100000+10; __int64 pri[MAX]; __int64 GetPrime(__int64 x,__int64 N){ int k=0; memset(pri,0,sizeof(pri)); for(__int64 i=2;i*i<=N;i++){//对N进行质因数分解 if(N%i==0){ pri[k++]=i; while(N%i==0)N/=i; } } if(N>1)pri[k++]=N;//因为N本身可能是素数 __int64 sum=0,val,num; for(__int64 i=1;i<(1<<k);i++){//此处相当于利用2进制来表示状态比如6 110 表示取第一个和第二个素数 2 3 val=1;num=0; for(int j=0;j<k;j++)if(i&(1<<j)){//应该j=0 。。半天找不着错。。。无语 val*=pri[j]; num++; } if(num&1){//奇加偶减是容斥原理 sum+=x/val; //如果val不是质数,x/val则表示与 它 的公因子 都互质的个数 // 如果是质数 x/val代表 1-x中 与 val不互质的个数 , //r(i)是某个质因子 N/r(i)所求 区间 1--N与 r(i)不互质的个数 //比如 1--8中与 6 不互质的个数为 1-8中为 8/2+8/3-8/(2*3) //由容斥原理 奇加偶减 便可求得 }else{ sum-=x/val; } } return x-sum; } void solve(){ int T; int d=0; scanf("%d",&T); while(T--){ __int64 a,b,N; scanf("%I64d%I64d%I64d",&a,&b,&N); __int64 ans=GetPrime(b,N)-GetPrime(a-1,N); printf("Case #%d: %I64d\n",++d,ans); } } int main(){ solve(); return 0; }
/* AC Time:2014-12-18 12:47 更新 */ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; const int MAX=100000+10; LL pri[MAX]; int Get_prime(LL n){ LL temp=n,k=0; for(int i=2;i*i<=n;i++){ if(temp%i==0){ pri[k++]=i; while(temp%i==0){ temp/=i; } } } if(temp>1)pri[k++]=temp;//本身是素数 return k; } LL Get_ans(LL x,int k){ int maxn=1<<k; LL ans=0; for(LL i=1;i<maxn;i++){ LL temp=1;int num=0; for(int j=0;j<k;j++){ if(i&(1<<j)){ temp*=pri[j]; num++; } } if(num&1)//不用考虑大于a的情况 ans+=x/temp; else ans-=x/temp; } return x-ans; } int main(){ int T,nCase=1; LL a,b,n; scanf("%d",&T); while(T--){ memset(pri,0,sizeof(pri)); scanf("%lld%lld%lld",&a,&b,&n); int k=Get_prime(n); LL ans=Get_ans(b,k)-Get_ans(a-1,k); printf("Case #%d: ",nCase++); printf("%lld\n",ans); } return 0; }
//超时代码。。。就是分解质因数i*i就是15ms,,时间差好大。。。。#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; const int MAX=10000+10; LL pri[MAX]; int Get_prime(LL n){ int k=0; for(int i=2;i<=n;i++){//这儿没有写成i*i<=n就超时。。。 if(n%i==0){ pri[k++]=i; while(n%i==0){ n/=i; } } } if(n!=1)pri[k++]=n; return k; } LL Get_ans(LL x,int k){ int maxn=1<<k; LL ans=0; for(LL i=1;i<maxn;i++){ LL temp=1;int num=0; for(int j=0;j<k;j++){ if(i&(1<<j)){ temp*=pri[j]; num++; } } if(num&1)//不用考虑大于a的情况 ans+=x/temp; else ans-=x/temp; } return x-ans; } int main(){ int T,nCase=1; LL a,b,n; scanf("%d",&T); while(T--){ memset(pri,0,sizeof(pri)); scanf("%lld%lld%lld",&a,&b,&n); int k=Get_prime(n); LL ans=Get_ans(b,k)-Get_ans(a-1,k); printf("Case #%d: ",nCase++); printf("%lld\n",ans); } return 0; }