同余

定义及性质

  定义:对于a、b两个整数,如果a和b的差能被m整除,那么a和b关于模m同余,记作a≡b(mod m)

  对于整数a,b,c和自然数m、n,模m同余满足:

  1、自反性:a≡a(mod m);

  2、对称性:若a≡b(mod m),则b≡a(mod m);

  3、传递性:若a≡b(mod m),b≡c(mod m),则a≡c(mod m);

  4、同加性:若a≡b(mod m),则a+c≡b+c(mod m);

  5、同乘性:若a≡b(mod m),则a*c≡b*c(mod m)

         若a≡b(mod m),c≡d(mod m),则a*c≡b*d(mod m);

  6、同幂性:若a≡b(mod m),则an≡bn(mod m);

  7、推论1:a*b mod k=(a mod k)*(b mod k)mod k;

  8、推论2:若a mod p=x,a mod q=x,p、q互质,则a mod p*q=x

    证明:设a div p=k1,b div q=k2

      ∴a=p*k1+x,b=k2*q+x

      ∴p*k1=q*k2

      ∵p、q互质

      ∴k1÷q必定为整数,即q|k1

      ∴a=k*p*q+x

例1:Semi-prime H-numbers

  形如4n+1的数称为H数,乘法在H数是封闭的。在这个集合中只能被1和本身整数整除的数称为H-素数,其余为H-合数。定义H-合成数为能且只能分解为2个H-素数的H-合数,求0~h中H-合成数的个数。  

  我们先考虑如何快速筛出H-素数,由于乘法在H数内封闭进行,并且有以下结论:

  1、两个H数乘起来一定是H数

  证明:我们设第一个H数等于4a+1,另一个为4b+1

    ∴(4a+1)(4b+1)=16ab+4a+4b+1=4(4ab+a+b)+1

    ∴乘积为H数

  2、对于一个H-合数,必定可以分解为若干个H-素数的乘积。

  3、对于一个H-素数,它的倍数一定是H-合数

  有了以上结论,我们就可以利用类似线性筛的方法,把H-素数筛出来,不过还有一点需要解决,因为乘法封闭进行,因此H-素数的倍数也不是正常意义上的倍数,只是(4n+1),其中n为正整数。

代码

#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e6+10;

int prime[100005],sum[N];
bool v[N],is[N];
int main()
{
    int cnt=0;
    for(int i=5;i<N;i+=4)
    {
        if(!v[i])prime[++cnt]=i;
        for(int j=i*5;j<N;j+=i*4)
            v[j]=1;
    }
//    cout<<cnt<<endl;
    for(int i=1;i<=cnt;i++)
        for(int j=1;j<=i&&prime[i]*prime[j]<N;j++)
            is[prime[i]*prime[j]]=1;
    for(int i=1;i<N;i++)
        sum[i]=sum[i-1]+is[i];
    int x;
    while(~scanf("%d",&x)&&x)
        printf("%d %d
",x,sum[x]);
}
原文地址:https://www.cnblogs.com/fangbozhen/p/11687599.html