容斥

来源:互联网 发布:淘宝修改评论链接 编辑:程序博客网 时间:2024/04/30 14:11

感觉就是一个模板其他的也没有啥,细节问题注意就好,循环的 时候,还有那个奇减偶加,这里求得是素因子的个数,其实就是欧拉函数了,先求一下素因子,然后根据容斥原理求得小于这个数的并且与这个数gcd不等于1的个数,最后减一下,就是最后与该数gcd为1的数的个数了。

题目链接:点击打开链接

代码:

#include<stdio.h>#include<algorithm>using namespace std;#include<string.h>//#include<bits/stdc++.h>int q[100000];int k;long long  rongchi(long long  a){    long long  sum1=0;//    int flag=1;    for(long long  i=1; i<(1ll<<k); i++)    {        long long sum=0;        long long sum2=1;        for(long long  j=0; j<k; j++)            if(i&(1ll<<j))            {                sum++;                sum2*=q[j];            }        if(sum &1)            sum1+=a/sum2 ;        else            sum1-=a/sum2;//        flag+=1;    }    return (a-sum1);}int main(){    int t;    int cas=1;    scanf("%d",&t);    while(t--)    {        long long a,b;        long long  n;        scanf("%I64d%I64d%I64d",&a,&b,&n);//        if(n==1)//        {//            printf("Case #%d: %I64d\n",cas++,b-a+1);//            continue;//        }//        if(a==b)//        {//            if(__gcd(a,n)==1)//                printf("Case #%d: 1\n",cas++);//            else//                printf("Case #%d: 0\n",cas++);//            continue;//        }        memset(q,0,sizeof(q));//        q[1]=1;        k=0;        for(long long  i=2; i*i<=n; i++)        {            if(!(n%i))            {                q[k++]=i;                while(n%i==0)                {                    n/=i;                }            }        }        if(n>1)            q[k++]=n;        printf("Case #%d: %I64d\n",cas++,rongchi(b)-rongchi(a-1));    }    return 0;}
然后这里没有必要筛选出素数的个数,有的代码筛选出素数的个数,不是太必要。

题目链接:点击打开链接

代码:

#include<stdio.h>#include<algorithm>using namespace std;#include<string.h>//#include<bits/stdc++.h>int q[100000];int k;long long  rongchi(long long  a){    long long  sum1=0;//    int flag=1;    for(long long  i=1; i<(1ll<<k); i++)    {        long long sum=0;        long long sum2=1;        for(long long  j=0; j<k; j++)            if(i&(1ll<<j))            {                sum++;                sum2*=q[j];            }        if(sum &1)            sum1+=a/sum2 ;        else            sum1-=a/sum2;//        flag+=1;    }    return (a-sum1);}int main(){//    int t;//    int cas=1;//    scanf("%d",&t);//    while(t--)//    {    long long a;    long long  n;    while(scanf("%I64d%I64d",&n,&a)!=EOF)    {//        if(n==1)//        {//            printf("Case #%d: %I64d\n",cas++,b-a+1);//            continue;//        }//        if(a==b)//        {//            if(__gcd(a,n)==1)//                printf("Case #%d: 1\n",cas++);//            else//                printf("Case #%d: 0\n",cas++);//            continue;//        }        memset(q,0,sizeof(q));//        q[1]=1;        k=0;        for(long long  i=2; i*i<=n; i++)        {            if(!(n%i))            {                q[k++]=i;                while(n%i==0)                {                    n/=i;                }            }        }        if(n>1)            q[k++]=n;        long long r=0,l=(1ll<<40);        while(r<l)        {            long long mid=(r+l)/2;            if(rongchi(mid)>=a)                l=mid ;            else                r=mid+1;        }        printf("%I64d\n",l);    }////    }    return 0;}
这里用到的是二分,这个二分我写了也算有一些题了吧,再写挫我也是跪了。


0 0
原创粉丝点击