hdu4135数的素数分解+容斥定理

题目链接点击打开链接

Co-prime

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 16   Accepted Submission(s) : 6
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.
 

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[sup]15[/sup]) and (1 <=N <= 10[sup]9[/sup]).
 

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}. [/hint]
 

Source
The Third Lebanese Collegiate Programming Contest

题意:a~b范围内于n互质的数的个数

我们转变为找不互质的个数

找到1~b内不互质的个数和1~(a-1)内不互质的个数

答案为(b-(a-1))-(solve(b)-solve(a-1));

因此我们需要找到先n的质因数

然后根据容斥定理奇加偶减得到不互质的数的个数

#include
#define LL __int64
using namespace std;
int t;
LL a,b,n;
LL num[110];
LL que[100010];
LL cnt;
void divid(LL x)//分解为质因子相乘
{
    cnt=0;
    for(LL i=2;i*i<=x;i++)
    {
        if(x%i==0)
        {
            while(x%i==0)
            {
                x=x/i;
            }
            num[++cnt]=i;
        }
    }
    if(x!=1)
        num[++cnt]=x;
}
LL solve(LL x)
{
    LL ans=0;
    LL k;
    LL t=0;
    que[0]=-1;
    for(LL i=1;i<=cnt;i++)
    {
        k=t;
        for(LL j=0;j<=k;j++)
        {
            que[++t]=-1*que[j]*num[i];
        }
    }
    for(LL i=1;i<=t;i++)
        ans=ans+(x/que[i]);
    return ans;
}
int main()
{
    scanf("%d",&t);
    int cas=0;
    while(t--)
    {
        cas++;
        scanf("%I64d%I64d%I64d",&a,&b,&n);
        divid(n);
        LL ans=(b-(a-1))-(solve(b)-solve(a-1));
        printf("Case #%d: ",cas);
        printf("%I64d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(C语言-ACM-算法-题解)