码迷,mamicode.com
首页 > 其他好文 > 详细

给定你一个数n,找出在[a,b]这个区间中和n互质的数的个数。

时间:2016-05-07 10:54:26      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:

    

解题思路:求[a,b]区间内与n互质的数的个数,我们可以转化为[1,b]内与n互质的数的个数减去[1,a-1]内与n互质的数的个数

而要求[1,b]内与n互质的数的个数,我们可以很自然地想到容斥原理

求解区间[a,b]中与k互质的个数 
首先对k进行质数分解,然后与这个因子GCD!=1则共有n/k
i

有计算重复的部分,因此利用 容斥原理: k1+k2+k3-k1*k2-.....求出与k不互质的个数,用总的减去即可

Description

给定你一个数n,请你统计出在[a,b]这个区间中和n互质的数的个数。两个数互质当且仅当他们除了1之外没有其他的公共因子或者他们最大的公共因子是1。1和任何数是互素的。

Input

第一行输入一个整数T(1 <= T <= 100),表示T组测试数据。接下来T行,每行3个整数a,b,n(1 <= a <=b <=10^15, 1<= n <= 10^9),用空格隔开。

Output

输出一个整数表示和n互质的数的个数。

Sample Input

2
1 10 2
3 10 5

Sample Output

5
6
<pre name="code" class="cpp">#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
long long s[1020],k;
void prime(long long m)//求一个数的素因子
{
    long long i;
       k=0;
    for(i=2;i*i<=m;i++)
    {
        if(m%i==0)
        {
            s[k++]=i;
            while(m%i==0)
                m/=i;
//printf("%d\n",m);
        }
    }
        if(m>1)
            s[k++]=m;

            //printf("###\n");
}
long long quc(long long m)//队列数组实现容斥原理
{
  long long p[10020],i,j,t=0,sum=0,z;
    p[t++]=-1;
    for(i=0;i<k;i++)
    {
        z=t;
        for(j=0;j<z;j++)
        {
            p[t++]=p[j]*s[i]*(-1);
        }
    }
    for(i=1;i<t;i++)
        sum+=m/p[i];
    return sum;
}
int main()
{
    long long n;
    scanf("%lld",&n);
    while(n--)
    {
        long long a,b,m,sum;
        scanf("%lld %lld %lld",&a,&b,&m);
           prime(m);
        sum=b-quc(b)-(a-1)+quc(a-1);
        printf("%lld\n",sum);
    }
}


给定你一个数n,找出在[a,b]这个区间中和n互质的数的个数。

标签:

原文地址:http://blog.csdn.net/maqinyao5566/article/details/51333973

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!