容斥原理 求M以内有多少个跟N是互质的

开始系统的学习容斥原理!通常我们求1~n中与n互质的数的个数都是用欧拉函数! 

但如果n比较大或者是求1~m中与n互质的数的个数等等问题,要想时间效率高的话还是用容斥原理!

本题是求[a,b]中与n互质的数的个数,可以转换成求[1,b]中与n互质的数个数减去[1,a-1]与n互质的数的个数。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define LL long long
#define maxn 70  

LL prime[maxn];
LL make_ans(LL num,int m)
{
    LL ans=0,tmp,i,j,flag;
    for(i=1;i<(LL)(1<<m);i++) //用二进制来1,0来表示第几个素因子是否被用到,如m=3,三个因子是2,3,5,则i=3时二进制是011,表示第2、3个因子被用到
    {
        tmp=1,flag=0;
        for(j=0;j<m;j++)
            if(i&((LL)(1<<j)))//判断第几个因子目前被用到
                flag++,tmp*=prime[j];
        if(flag&1)//容斥原理,奇加偶减
            ans+=num/tmp;
        else
            ans-=num/tmp;
    }
    return ans;
}  

int main()
{
    int T,t=0,m;
    LL n,a,b,i;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d%I64d%I64d",&a,&b,&n);
        m=0;
        for(i=2;i*i<=n;i++) //对n进行素因子分解
            if(n&&n%i==0)
            {
                prime[m++]=i;
                while(n&&n%i==0)
                    n/=i;
            }
        if(n>1)
            prime[m++]=n;
        printf("Case #%d: %I64d\n",++t,(b-make_ans(b,m))-(a-1-make_ans(a-1,m)));
    }
    return 0;
} 
时间: 2024-10-24 18:27:14

容斥原理 求M以内有多少个跟N是互质的的相关文章

埃氏筛法(求n以内有多少个素数)

题目大意:给定整数n,请问n以内有多少个素数 思路:想必要判断一个数是否是素数,大家都会了,并且可以在O(根号n)的复杂度求出答案,那么求n以内的素数呢,那样求就显得有点复杂了,下面看一下这里介绍的??氏算法 其实呢,就是求出第一个素数,然后把n以内它的倍数都删掉就行了,很简单.然后找下一个素数,同样方法····· 看代码 #include<iostream> #include<string.h> #include<map> #include<cstdio>

(hdu step 7.2.2)GCD Again(欧拉函数的简单应用——求[1,n)中与n不互质的元素的个数)

题目: GCD Again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 125 Accepted Submission(s): 84   Problem Description Do you have spent some time to think and try to solve those unsolved problem afte

(hdu step 2.1.6)找新朋友(欧拉函数的简单使用:求与n互质的元素的个数)

题目: 找新朋友 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2788 Accepted Submission(s): 1307   Problem Description 新年快到了,"猪头帮协会"准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大

一道面试题:用多线程求1000以内的素数有多少个?并给出消耗时间

我曾经去一个公司面试,遇到这么一个题目:求1000以内的素数有多少个?用多线程实现,并给出消耗时间.我想了半天,没有想出多线程的解决方案.今天因为机缘到了,我浅谈下我的解法. 这道题,显然得考虑两个问题: 1.多线程的问题 2.算法性能问题 有人觉得1000以内还考虑什么算法性能?这肯定很快.但是话说回来,这个都有必要用多线程吗?如果我们求10000000以内的素数有多少个?是不是必须考虑以上两个问题了?多线程和算法优化的目的都是为了提高程序执行的效率.我们首先来考虑算法问题,什么是素数?素数:

求100以内的质数

求100以内的质数. 1 num = [2] 2 i = 3 3 while i < 101: 4 j = 2 5 while j < i: 6 if i % j == 0: 7 break 8 else: 9 j = j + 1 10 continue 11 else: 12 num.append(i) 13 i = i + 1 14 print(num)

求1-100的和&amp;&amp;.输入一个数n,打印1-n出来&amp;&amp;求1-100以内所有偶数的和

1.求1-100的和 int b = 0; for (int i = 1; i <=100; i++) { b = b+i; } Console.WriteLine("1-100的和b为:" + b); 2.输入一个数n,打印1-n出来 Console.WriteLine("请输入一个数n:"); int n = int.Parse(Console.ReadLine()); for (int i = 1; i <= n; i++) { Console.W

python 求10亿以内和987654互质正整数的和

加群看见的 但是计算好慢,谁有更优的算法,麻烦说一下. ? 1 2 3 4 5 6 7 8 9 10 factor=[] for x in xrange(1, 987654//2+1):     if 987654%x==0:         factor.append(x) sum=0 for y in xrange(1, 1000000000):     for z in factor:         if y%z == 0:             sum+=y print sum 51

openjudge 14:求10000以内n的阶乘

14:求10000以内n的阶乘 总时间限制: 5000ms 内存限制: 655360kB 描述 求10000以内n的阶乘. 输入 只有一行输入,整数n(0<=n<=10000). 输出 一行,即n!的值. 样例输入 100 样例输出 93326215443944152681699238856266700490715968264381621468592963895217599993229915.... 1 #include <algorithm> 2 #include <bit

AC日记——求10000以内n的阶乘 openjudge 1.6 14

14:求10000以内n的阶乘 总时间限制:  5000ms 内存限制:  655360kB 描述 求10000以内n的阶乘. 输入 只有一行输入,整数n(0<=n<=10000). 输出 一行,即n!的值. 样例输入 100 样例输出 9332621544394415268169923885626670049071596826438162146859296389521759999322991560894146397615651828625369792082722375825118521091