简单数论

· · 算法·理论

一.斐蜀定理

(1).内容:

a,b \in \mathbb{Z} 且不全为0,则\forall x,y \in \mathbb{Z},满足\gcd(a,b) \mid ax+by\exists x,y \in \mathbb{Z},使得ax+by=\gcd(a,b)

(2).推广

1.逆定理

a,b \in \mathbb{Z} 且不全为0,若d>0,且d \mid a,d \mid b\exists x,y \in \mathbb{Z},使得ax+by=d,则d=\gcd(a,b)

2.扩展

显然可以扩展到多个整数。

(3).进一步结论

对于a,b \in \mathbb{N},n \in \mathbb{Z}a \perp b,有以下几个结论:

  1. C=ab-a-b,显然有C为奇数。
  2. 可得
\begin{cases} t=C,\forall x,y \in \mathbb{N}, ax+by \ne t\\ t>C,\exists x,y \in \mathbb{N}, ax+by = t \end{cases}
  1. 进而可得:对于方程 ax+by=c,在 [0,C] 中,恰有 \frac{(a-1)(b-1)}{2}c 满足条件,即\forall n \in \mathbb{N},n,C-n 中有且只一个满足条件。

    二.丢番图方程

    (1).形态:a_1x_1^{b_1}+...+a_nx_n^{b_n}=c,a_{1...n},b_{1...n},c \in \mathbb{Z}

    (2).二元线性丢番图方程:ax+by=c,a,b,c \in \mathbb{Z}

    1.定理:

    对于a,b,c\in\mathbb{Z},\exists x,y \in \mathbb{Z},使得ax+by=c\iff\gcd(a,b)\mid c

    2.求解:

    a.求出一个解:扩展欧几里得

    先求解ax+by=\gcd(a,b) 不妨假设a>b,\gcd(a,b)=pa+qb 则有 \begin{aligned} ax+by &= \gcd(a,b)\\ &= \gcd(b,a \bmod b)\\ &= pb+q(a \bmod b)\\ &= qa+(p-q*\lfloor\frac{a}{b}\rfloor)b \end{aligned}
int extended_gcd(int a,int b,int &x,int &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    int ret,xx=x,yy=y;
    ret=extended_gcd(b,a%b,x,y);
    x=yy,y=xx-a/b*yy;
    return ret;
} 

b.所有解

x_0,y_0 为原方程一组解,则有

\begin{cases} x=x_0+\frac{b}{\gcd(a,b)}t\\ y=y_0-\frac{a}{\gcd(a,b)}t \end{cases} 为原方程一组解,其中t为任意整数

特殊地,我们有最大正整数解和最小正整数解的关系为:

\begin{cases} x_{max}=\frac{c-y_{min}*b}{a}\\ y_{max}=\frac{c-x_{min}*a}{b} \end{cases}

三.线性同余方程

(1).形态:ax \equiv c \pmod b

(2).求解:

显然有 ax \equiv c \pmod b \iff ax+by=c
int extended_gcd(int a,int b,int &x,int &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    int ret,tmp;
    ret=extended_gcd(b,a%b,x,y);
    tmp=x,x=y,y=tmp-a/b*y;
    return ret;
} 
bool linear_equation(int a,int b,int c,int &x,int &y){
    int d=extended_gcd(a,b,x,y);
    if(c%d) return 0;
    int k=c/d;
    x*=k,y*=k;
    return 1;
}

四.第一类指数同余方程

(1).形式:a^x\equiv b\pmod p

(2).求解

x=kt-m,其中 t=\lfloor\sqrt p\rfloor0\le m\le t1\le k\le\lfloor\frac{p}{t}\rfloor

则有:a^{kt-m}\equiv b\pmod p

a^{kt}b^{-1}\equiv a^m\pmod p

预处理出 a^0\bmod p,a^1\bmod p,\dots,a^t\bmod p

枚举 k,计算看有没有匹配上的数。

时间复杂度:O(\sqrt p)

五.第二类指数同余方程

(1).形式:x^k\equiv b\pmod p

(2).求解:

ap 的一个原根,先求出 b\equiv a^m\pmod p

假定 x\equiv a^y

a^{ky}\equiv a^m\pmod p

a^{ky-m}\equiv 1\pmod p

ky-m\equiv 0\pmod {p-1}

六.逆元

a \times x \equiv 1 \pmod b,则xa\bmod b意义下的倒数,记作a^{-1}

显然有 \frac{a}{b} \pmod b=a\times b^{-1} \pmod b

  1. 扩展欧几里得: 前提:p不一定是质数,a为正整数,a \perp p 同解线性同余方程
    int extended_gcd(int a,int b,int &x,int &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    int ret,xx=x,yy=y;
    ret=extended_gcd(b,a%b,x,y);
    x=yy,y=xx-a/b*yy;
    return ret;
    } 
    bool exgcd(int a,int b,int &x,int &y){
    int d=extended_gcd(a,b,x,y);
    if(1%d) return 0;
    int k=1/d;
    x*=k,y*=k;
    return 1;
    }
  2. 快速幂:

    前提:p为质数,a为正整数,a \perp p

    根据费马小定理:若p为质数,a \perp p,则a^{p-1} \equiv 1 \pmod p

    则有

\begin{aligned} ax &\equiv 1 \pmod p\\ ax &\equiv a^{p-1} \pmod p\\ x &\equiv a^{p-2} \pmod p \end{aligned}
  1. 线性算法: 前提:p为质数,i为正整数

显然有 1^{-1} \pmod p

不妨设kp/i的商,r为p/i的余数

\therefore k*i+r=p \therefore k*i+r \equiv 0 \pmod p

同乘i^{-1}r^{-1}可得:

\therefore k*i^{-1}+i^{-1}\equiv 0 \pmod p \therefore i^{-1} \equiv -k*r^{-1} \pmod p \therefore i^{-1} \equiv -\lfloor \frac{p}{i} \rfloor * (p \bmod i)^{-1} \pmod p
inv[1]=1;
for(int i=2;i<p;i++)
  inv[i]=(p-p/i)*inv[p%i]%p;

七.原根

mod 的原根:g 是原根当且仅当 g^0,g^1,\dots,g^{p-2}mod 两两不同。

若模 mod 意义下原根存在:

欧拉准则:\left(\dfrac{a}{p}\right)\equiv a^{\frac{p-1}{2}}\pmod p

二次互反律:对于奇素数 p,q,有 \left(\dfrac{p}{q}\right)\left(\dfrac{q}{p}\right)=(-1)^{\frac{(p-1)(q-1)}{4}}

求解 x

前提:p 为奇素数。

随机一个 a,使得 a^2-n 为非二次剩余,令 w=\sqrt{a^2-n}

x=(a+w)^{\frac{p+1}{2}}

LL w,n,p; 
struct num{
    LL x,y;
    num operator *(const num b){
        num tmp;
        tmp.x=((x*b.x%p+y*b.y%p*w%p)%p+p)%p;
        tmp.y=((x*b.y%p+y*b.x%p)%p+p)%p;
        return tmp;
    }
};
LL qpow(num x,LL y,LL Mod=mod) {
    if(y==0) return 1;
    num res=x; y--;
    for(;y;y>>=1,x=x*x)
        if(y&1) res=res*x;
    return res.x%Mod;
}
LL cipolla(LL n,LL p){
    n%=p;
    if(qpow(n,(p-1)/2,p)==p-1) return -1;
    LL a;
    while(1){
        a=(rnd_64()>>1ll)%p;
        w=(((a*a)%p-n)%p+p)%p;
        if(qpow(w,(p-1)/2,p)==p-1) break;
    }

    num x={a,1};
    return qpow(x,(p+1)/2,p);
}
void solve(){
    cin>>n>>p;
    if(!n){
        cout<<"0\n";
        return ;
    }
    LL ans1=cipolla(n,p),ans2=p-ans1;
    if(ans1==-1) cout<<"Hola!\n";
    else {
        if(ans1==ans2) cout<<ans1<<"\n";
        else cout<<min(ans1,ans2)<<" "<<max(ans1,ans2)<<"\n";
    }
    return ;
}

九.中国剩余定理

(1).内容:

若自然数 m_{1...r} 两两互质,记 M=m_1m_2...m_r 则方程:

\begin{cases} x \equiv a_1 \pmod {m_1}\\ x \equiv a_2 \pmod {m_2}\\ ...\\ x \equiv a_r \pmod {m_r} \end{cases} ## (2).过程: 1. 计算 $n_i=\frac{M}{m_i}
  1. 计算 n_i\bmod m_i 意义下的逆元 {n_i}^{-1}
  2. 计算 c_i=n_i*{n_i}^{-1}(不对 m_i 取模)
  3. 则方程在 \bmod M 意义下的唯一解为:x=\sum_{i=1}^{r}a_ic_i \pmod M
    int extended_gcd(__int128 a,__int128 b,__int128 &x,__int128 &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    __int128 ret,tmp;
    ret=extended_gcd(b,a%b,x,y);
    tmp=x,x=y,y=tmp-a/b*y;
    return ret;
    }
    signed main(){
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>r;
    for1(i,1,r) cin>>m[i]>>a[i],M*=m[i];
    for1(i,1,r){
        n[i]=M/m[i];
        extended_gcd(n[i],m[i],x,y);
        c[i]=n[i]*x;
        madd(ans,a[i]*c[i],M);
    }
    cout<<ans;
    return 0;
    }

    (3).扩展中国剩余定理:

    若模数不两两互质。

先考虑 x \equiv a_1 \pmod {m_1},x \equiv a_2 \pmod {m_2}

转化成不定方程 x=m_1p+q_1=m_2q+a_2

m_1p-m_2q=a_2-a_1

\gcd(m_1,m_2)\nmid(a_2-a_1) 则无解。

否则可以转化成 x\equiv m_1p+a_1\pmod {lcm(m_1,m_2)}

__int128 extended_gcd(__int128 a,__int128 b,__int128 &x,__int128 &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    __int128 ret,tmp;
    ret=extended_gcd(b,a%b,x,y);
    tmp=x,x=y,y=tmp-a/b*y;
    return ret;
}
bool linear_equation(__int128 a,__int128 b,__int128 c,__int128 &x,__int128 &y){
    __int128 d=extended_gcd(a,b,x,y);
    if(c%d) return 0;
    __int128 k=c/d;
    x*=k,y*=k;
    return 1;
}
void solve(){
    cin>>r;
    for1(i,1,r) {
        rin(m); rin(a);
        linear_equation(M,-m,a-A,p,q);
        A=M*p+A,M=lcm(M,m);
        madd(A,M,M);
    }
    rout(A);
    return ;
}

(4).大部翻倍法

void merge(LL &a1,LL &m1,LL a2,LL m2){
    if(m1<m2) swap(m1,m2),swap(a1,a2);
    while(a1%m2!=a2) a1+=m1;
    m1=lcm(m1,m2);
}
void solve(){
    cin>>n;
    v=0,d=1;
    for1(i,1,n){
        cin>>a>>m;
        a%=m;
        merge(v,d,a,m);
    }
    cout<<v<<"\n";
}

十.积性函数

(1).定义

积性函数:对于函数 f(x),若 \forall a,b\in\mathbb{N}^+,\gcd(a,b)=1,f(ab)=f(a)f(b),则称 f(x) 为积性函数。

完全积性函数:对于函数 f(x),若 \forall a,b\in\mathbb{N}^+,f(ab)=f(a)f(b),则称 f(x) 为完全积性函数。

其中:\varepsilon(n)=\left[n=1\right],I(n)=1,id(n)=n

积性函数的性质:

\sum\limits_{d\mid n}\mu(d)=\varepsilon(n),\mu\ast1=\varepsilon

3.求法

线性筛:

void get_mu(int n){
    mu[1]=1;
    for1(i,2,n){
        if(!vis[i]) pri.p_b(i),mu[i]=-1;
        for(int j: pri){
            if(i>n/j) break;
            vis[i*j]=1;
            if(i%j==0){
                mu[i*j]=0;
                break;
            }
            mu[i*j]=-mu[i];
        }
    }
}

(4).约数之和 \sigma 与 约数个数 d

1.定义

n=p_1^{\alpha_1}\times p_2^{\alpha_2}\times\dots p_n^{\alpha_n}

则:

d(n)=(1+\alpha_1)\times(1+\alpha_2)\times\dots\times(1+\alpha_n) \sigma(n)=(1+p_1^1+p_1^2+\dots+p_1^{\alpha_1})\times(1+p_2^1+p_2^2+\dots+p_2^{\alpha_1})\times\dots\times(1+p_n^1+p_n^2+\dots+p_n^{\alpha_1})
$=\prod\limits_{i=1}^n(\sum_{j=0}^{\alpha_i}p_i^j)$
$=\prod\limits_{i=1}^n\frac{1-p_i^{\alpha_i+1}}{1-p_i}$

2.求法

  1. 线性筛求 d ```cpp void make_d(){ t[1]=d[1]=1; for1(i,2,n){ if(!vis[i]) pri.p_b(i),t[i]=1,d[i]=2; for(int j: pri){ if(i>n/j) break; vis[i*j]=1; if(i%j==0){ t[i*j]=t[i]+1; d[i*j]=d[i]*(t[i*j]+1)/(t[i]+1); break; } t[i*j]=1; d[i*j]=d[i]*d[j]; } } } ```
  2. 线性筛求 \sigma ```cpp void make_sgm(){ sigma[1]=1; for1(i,2,n){ if(!vis[i]) pri.p_b(i),t[i]=i+1,sigma[i]=i+1; for(int j: pri){ if(i>n/j) break; vis[i*j]=1; if(i%j==0){ t[i*j]=t[i]*j+1; sigma[i*j]=sigma[i]*t[i*j]/t[i]; break; } t[i*j]=j+1; sigma[i*j]=sigma[i]*sigma[j]; } } } ``` ****** # 十一.欧拉定理 ## (1).内容: 若 $\gcd(a,m)=1$,则 $a^{\varphi(m)} \equiv 1\pmod m

    (2).扩展:

    a^b\equiv \begin{cases} a^{b\bmod\varphi(m)},& \gcd(a,m)=1\\ a^b,& \gcd(a,m)\ne 1,b<\varphi(m)\\ a^{(b\bmod\varphi(m))+\varphi(m)}&\gcd(a,m)\ne 1,b\ge\varphi(m) \end{cases} \pmod m

    十二.威尔逊定理

    对于素数 p(p-1)!\equiv-1\pmod p

    十三.数论分块

    一般用来求形如 \sum_{i=1}^nf(i)g(\lfloor\frac{n}{i}\rfloor)

若可以 O(1) 计算 f(r)-f(l) 时。

我们考虑将 \lfloor\frac{n}{i}\rfloor 相同的数放一起计算以使复杂度降至 O(\sqrt n)

UVA11526 H(n)

LL H(LL n){
    LL ans=0;
    for(LL i=1,j;i<=n;i=j+1){
        j=n/(n/i);
        ans+=(j-i+1)*(n/i);
    }
    return ans;
}