南京理工大学第八届程序设计大赛(校外镜像) - count_prime (容斥原理)

count_prime

Time Limit: 1000ms
Memory Limit: 65536KB

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


标准题解:

容斥原理、先对n分解质因数,分别记录每个质因数,那么所求区间内与某个质因数不互质的个数就是n/r(i),假设r(i)是r的某个质因子 假设只有三个质因子,总的不互质的个数应该为p1+p2+p3-p1p2-p1p3-p2p3+p1p2*p3, 及容斥原理,pi代表n/r(i),即与某个质因子不互质的数的个数,当有更多个质因子的时候,可以用状态压缩解决,二进制位上是1表示这个质因子被取进去了。如果有奇数个1就相加,反之则相减。


代码:

#include <iostream>
using namespace std;
long long int primeNum[1000];
long long int num = 0;
void findPrime(long long int a)
{
    num = 0;
    for(int i = 2; i * i <= a; i++)
    {
        if(a % i == 0)
        {
            primeNum[num] = i;
            num++;
            while(a%i == 0)
                a = a / i;
        }
    }
    if(a > 1)
    {
        primeNum[num] = a;
        num++;
    }
}
long long int hasaki(long long int n)
{
    long long int que[10000],k,t=0,sum=0;
    que[t]=-1;
    t++;
    for(long long int i=0;i<num;i++)
    {
        k=t;
        for(long long int j=0;j<k;j++)
        {
            que[t]=que[j]*primeNum[i]*(-1);
            t++;
        }
    }
    for(int i=1; i<t;i++)
        sum = sum + n/que[i];
    return sum;
}
int main()
{
    int t;
    cin >> t;
    while(t -- )
    {
        long long int a,b,n;
        cin >> a >> b >> n;
        findPrime(n);
        long long int ans;
        ans = b - hasaki(b) - (a-1 - hasaki(a-1));
        cout << ans <<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值