题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4135
思路:给定一段区间【A,B】,再给你一个数N,题目让你求【A,B】这一段区间与N互质的数的个数(不妨设为ans)。求解之前不妨先转化一下:
求【1,A-1】中与N互质的个数,假设为sum1,再求【1,B】中与N互质的个数,假设为sum2。所以经过转化之后,ans=sum2-sum1。就是【A,B】=【1,B】-【1,A-1】,好啦,基本过程以经操作完成。
代码:
/*题目是让求给定一段区间【A,B】,再给出一个数m,求该段区间与m互
质的数的个数*/
//#include<bits/stdc++.h>
#include<iostream>
#include<string.h>
long long temp[100];
long long num;
using namespace std;
typedef long long ll;
void out(ll n){ // 分解质因子
num=0;
for(ll i=2;i*i<=n;i++)
{
if(n%i==0)
{
temp[num++]=i;
while(n%i==0)
n=n/i;
}
}
if(n>1)
temp[num++]=n;
/* for(int i=0;i<num-1;i++)
cout<<temp[i]<<" ";
cout<<temp[num-1]<<endl; */}
ll zjj(ll t){ //返回互质的个数
ll ans,res,sum=0; //先求出不互质的,用到了容斥定理
for(ll i=1;i<(1<<num);i++)
{
ans=1,res=0;
for(ll j=0;j<num;j++)
{
if(1&i>>j) //if(i&1<<j)这两种方式等价
{
ans=ans*temp[j];
res++;
}
}
if(res&1)
sum+=t/ans;
else
sum-=t/ans;
}
return t-sum; //总数减去不互质的即为互质的
}
int main(){
ll t,ans1=1;
cin>>t;
while(t--){
//memset(temp,0,sizeof(temp));
ll a,b,c;
cin>>a>>b>>c;
out(c);
cout<<"Case #"<<ans1++<<": "<<zjj(b)-zjj(a-1)<<endl;
}
return 0;
}
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6998 Accepted Submission(s): 2767 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.
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 <= 1015) and (1 <=N <= 109).
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 Hint In the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.
|