數論基礎

0、一些結論

  1. (hdu3501)求1…N中與N互質的數的和:ans=phi(n)*n/2

1、歐幾里德算法

int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b , a%b);
}

int lcm(int a, int b)
{
    return a/gcd(a,b)*b;//防止溢出

}

2、Eratosthenes篩法

int m = sqrt(int n+0.5);
memset(vis, 0, sizeof(vis));
for(int i = 2; i <= m; i++)
{
    if(!vis[i])
    for(int j = i*i; j <= n; j += i)
    {
        vis[j] = 1;
    }
}

3、擴展歐幾里德算法

4、同餘與模算術

同餘:a 與 b 在模 m 的情形下同餘,即爲 a, b 除以 m 的餘數相等。
剩餘系:mod m = k 的整數。

1)同餘定理

//(a+b)%n=(a%n+b%n)%n

//(a-b)%n=(a%n-b%n+n)%n

//a*b%=(a%n)*(b%n)%n;

int mul_mod(int a, int b, int n)
{
    a %= n;
    b %= n;
    return (int)((long long)a * b % n);
}

2)大數取模

scanf("%s%d",n, &m);
int len = strlen(n);
int ans = 0;
for(int i = 0; i < len; i++)
{
    ans=(int)((long long)ans*10 + n[i] - '0') % m);
}
printf("%d\n",ans);

3)冪取模

int pow_mod(LL a,LL n,int m)
{
    if(n==0) return 1;
    LL x=pow_mod(a,n/2,m);
    LL ans=x*x%m;
    ans=ans%m;
    if(n%2==1) ans=ans*a%m;
    return (int)ans;
}

4)矩陣快速冪

struct Matrix
{
    int mp[N][N];
};

Matrix Mul(Matrix a,Matrix b)
{
    int i,j,k;
    Matrix c;
    for(i=0; i<N; i++)
        for(j=0; j<N; j++)
        {
            c.mp[i][j]=0;
            for(k=0; k<N; k++)
            {
                c.mp[i][j]+=a.mp[i][k]*b.mp[k][j];
                c.mp[i][j]%=M;
            }
        }
    return c;
}

/*
Matrix Pow(Matrix t,int n)
{
    if(n==1) return t;
    Matrix c=Pow(t,n/2);
    if(n&1)
        return Mul(Mul(c,c),t);
    else
        return Mul(c,c);
}
*/

Matrix Pow(Matrix a,int n)
{
    Matrix c;
    for(i=0;i<N;i++)
        c.mp[i][i]=1;
    while(n)
    {
        if(n&1) c=Mul(c,a);
        a=Mul(a,a);
        n/=2;
    }
    return c;
}

5、歐拉函數(計算小於n且與n互素的整數個數)

1)計算小於n且與n互素的整數個數

int euler_phi(int n)
{
    int m=(int)sqrt(n+0.5);
    int ans=n;
    for(int i=2; i<=m; i++)
        if(n%i==0)
        {
            ans=ans/i*(i-1);
            while(n%i==0) n/=i;
        }
    if(n>1) ans=ans/n*(n-1);
    return ans;
}

2)1~n中所有數的歐拉phi函數值

void phi_table(int n)
{
    for(int i=2;i<=n;i++)   phi[i]=0;
    phi[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(!phi[i])//判斷素數
        {
            for(int j=i;j<=n;j+=i)
            {
                if(!phi[j]) phi[j]=j;
                phi[j]=phi[j]/i*(i-1);
            }
        }
    }
}

6、乘法逆元

  • 若 (k, m) = 1,則存在一個 k1 ,使得k1k = kk1 = 1 (mod m),稱其爲 k 在模 m 下的乘法逆元。
  • Bezout 定理:如果 (a, b) = g,那麼存在整數 x, y 使得 ax + by = g。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章