hdu 4135 Co-prime(容斥原理)

本文介绍了一个算法问题:计算两个整数范围内与给定数互质的整数数量。通过分解质因数并运用容斥原理,文章提供了一种有效的解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Co-prime
 
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 <= 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}.
不懂容斥原理的话,这有容斥原理的上手题: 点击打开链接
有两个原理:
1. 在[1,n]之间与m互质的数的个数=[1,n]之间的总个数-[1,n]之间与m不互质的数的个数
2. [1,n]之间与m互质的数的数量 = n - (包含一个质因子的数的个数)+(包含2个质因子的数的个数)-(包含3个质因子的数的个数)+(包含4个质因子的数的个数).....
代码:
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;

#define LL long long int

vector<int>q;
LL b[1000];

void div(int  k)//对k分解质因子
{
    for(int i=2;i*i<=k;i++)
    {
        if(k%i==0)
            q.push_back(i);
        while(k%i==0)
            k/=i;
    }
    if(k>1)
        q.push_back(k);
}
//容斥原理计算[1,n]内有多少个与k互质的数
LL cont(LL n)
{
    LL g=0,sum=n;
    b[++g]=1;
    for(LL i=0;i<q.size();i++)
    {
        LL t=g;
        for(LL j=1;j<=g;j++)
        {
            b[++t]=-q[i]*b[j];
            sum+=n/b[t];
        }
        g=t;
    }
    return sum;
}

int main()
{
    int t,m=0;
    scanf("%d",&t);
    while(m<t)
    {
        q.clear();
        LL a,b;
        int k;
        scanf("%lld%lld%d",&a,&b,&k);
        div(k);
        printf("Case #%d: %lld\n",cont(b)-cont(a-1));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值