蓝桥杯ABC组 数论知识合集

news2025/4/8 6:10:31

Note Of Note

  1. 同余方程中是可以正常进行分数的约分和去分母的
  2. e x g c d exgcd exgcd 在使用时要保证 a , b a,b a,b 都是非负数
  3. a a a b b b 互质不代表 a , b a,b a,b 都为质数( 4 4 4 5 5 5 互质,但是 4 4 4 不是质数)
  4. 两个相邻的正整数必定是互质的
  5. 两个互质的数 a , b a,b a,b 凑不出来(特指用加法)的最大整数为 ( a − 1 ) ( b − 1 ) − 1 (a-1)(b-1)-1 (a1)(b1)1
  6. 一个大数的约数个数平均是 l o g n logn logn 级别,最坏是 n \sqrt{n} n 级别,int 范围内一个数的约数最多为 1600 个
  7. 1 到 n 的约数个数之和大概是在 n l o g n nlogn nlogn 这个级别
  8. 1 到 n 之间的质数大概有 n ln ⁡ n \dfrac{n}{\ln n} lnnn
  9. 只有完全平方数的因子个数为奇数个
  10. 任何一个合数 n 必定包含一个不超过 n \sqrt n n 的质因子

TODO

分解质因数,判断质数,分解因数时循环的范围与写法

质数

质数与合数是针对所有**大于 1 1 1 的自然数来定义的(所有小于等于 1 1 1 **的数都不是质数)。

判断质数

用试除法判断,时间复杂度为 O ( n ) O(\sqrt{n}) O(n )

public static boolean isPrime(int n){
        if(n < 2) return false;
        for(int i = 2;i <= n / i;i ++)
            if(n % i == 0) return false;
        return true;
}

也可以先把质数筛出来,然后用质数去试除,只需要以 O ( n ) O(n) O(n) 的时间复杂度预处理出 1 1 1 n \sqrt n n 里所有素数,每次判断的时间复杂度就可以降低到 O ( n ln ⁡ n ) O(\frac{\sqrt n}{\ln \sqrt n}) O(lnn n )

分解质因数

算术基本定理

任何一个大于 1 1 1 的自然数 n n n,如果本身不是质数,那么就可以唯一分解为有限个质数的乘积, N = p 1 a 1 × p 2 a 2 × p 3 a 3 × ⋯ × p n a n N=p_1^{a_1}\times p_2^{a_2}\times p_3^{a_3}\times \cdots \times p_n^{a_n} N=p1a1×p2a2×p3a3××pnan,这里 p 1 < p 2 < p 3 < ⋯ < p n p_1 < p_2 < p_3 < \cdots < p_n p1<p2<p3<<pn 且均为质数,其中指数 a i a_i ai 是正整数

分解质因数

最坏为 O ( n ) O(\sqrt{n}) O(n )

n n n 中最多只包含一个大于 n \sqrt{n} n 的质因子

public static void divide(int n){
        for(int i = 2;i <= n / i;i ++){
            if(n % i == 0){
                int s = 0;
                while(n % i == 0){
                    n /= i;
                    s ++;
                }
                printf("%d %d\n",i, s);
            }
        }
        if(n > 1) printf("%d %d\n",n, 1);
        printf("\n");
}

可以先预处理出 1 ∼ n 1\sim n 1n 中的素数,直接用素数去分解,单次分解的时间复杂度可以降到 O ( n ln ⁡ n ) O(\frac{\sqrt n}{\ln \sqrt n}) O(lnn n )

这个时间复杂度是比较暧昧的,大概能比 O ( n ) O(\sqrt n) O(n ) 低一个数量级, 1 0 6 10^6 106 的数据大概只需要 100 次计算即可。

筛质数

欧拉筛

时间复杂度为 O ( n ) O(n) O(n)

原理说明:

每个合数都只会被自己最小质因子筛掉,假设该最小质因子为 p j p_j pj,则合数 x = p j ∗ i x=p_j*i x=pji,因为 p j p_j pj从小到大依次枚举的,如果

  • i   m o d   p j ≠ 0 i\bmod p_j \ne 0 imodpj=0,说明 p j p_j pj 小于 i i i 的所有质因子,那么 p j p_j pj 一定是 p j ∗ i p_j*i pji 的最小质因子
  • i   m o d   p j = 0 i\bmod p_j = 0 imodpj=0,第一个这样的 p j p_j pj 也一定时 p j ∗ i pj*i pji 的最小质因子,而且可以停止枚举了,因为 p j + 1 p_{j+1} pj+1 已经大于了 i i i 的最小质因子了
int primes[N], cnt=0;     // primes[]存储所有素数
boolean st[N];         // st[x]存储x是否被筛掉

void getPrimes(int n){
    for (int i = 2; i <= n; i ++ ){
        if (!st[i]) primes[++cnt] = i;
        for (int j = 1; primes[j] <= n / i; j ++ ){
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}

约数

试除法求约数

public static void getDivisors(int n){
        List<Integer> list = new ArrayList<>();
        for(int i=1;i<=n/i;i++){
            if(n%i==0){
                list.add(i);
                if(i!=n/i) list.add(n/i);
            }
        }
        list.sort((a,b)->{return a-b;});
        for(Integer a : list)
            cout.print(a+" ");
        cout.println();
}

求 n 的正约数集合像上面这么求的话,时间复杂度为 O ( n ) O(\sqrt n) O(n ),如果连续求 1 到 n 的正约数集合的话,就是 O ( n n ) O(n\sqrt n) O(nn )

我们可以用倍数法来求:
BCA42F8AC396C1E365ACF3E84172F197

直接枚举因数,然后把因数添加到相应的数的集合里,时间复杂度为 O ( n + n 2 + n 3 + n 4 + ⋯ + n n = O ( n log ⁡ n ) O(n+\frac{n}{2}+\frac{n}{3}+\frac{n}{4}+\cdots+\frac{n}{n}=O(n\log n) O(n+2n+3n+4n++nn=O(nlogn)

static List<Integer>[] factor;
public static void getFactors(int n){
	factor = new ArrayList[n+1];
	for(int i=1;i<=n;i++) factor[i] = new ArrayList<>();
	// 枚举因子
	for(int i=1;i<=n;i++)
		// 枚举倍数
		for(int j=1;j<=n/i;j++)
			factor[i*j].add(i);
}

约数相关公式

如果 N = p 1 a 1 × p 2 a 2 × p 3 a 3 × ⋯ × p n a n N=p_1^{a_1}\times p_2^{a_2}\times p_3^{a_3}\times \cdots \times p_n^{a_n} N=p1a1×p2a2×p3a3××pnan,那么:

  • N N N 的约数个数为 ( a 1 + 1 ) × ( a 2 + 1 ) × ⋯ × ( a n + 1 ) (a_1+1)\times(a_2+1)\times \cdots \times(a_n+1) (a1+1)×(a2+1)××(an+1)
  • N N N 的约数之和为 ( p 1 0 + p 1 1 + ⋯ + p 1 a 1 ) × ⋯ × ( p n 0 + p n 1 + ⋯ + p n a n ) (p_1^0+p_1^1+ \cdots + p_1^{a_1})\times \cdots \times (p_n^0+p_n^1+ \cdots + p_n^{a_n}) (p10+p11++p1a1)××(pn0+pn1++pnan)

以上的公式可以这么理解:

  • 约数个数相当于是乘法原理,每个指数都可以选一个值( 0 ∼ a i 0 \sim a_i 0ai,共 a i + 1 a_i+1 ai+1个数),只要有一个指数的值不同,数就不一样(算术基本定理),所以全部乘起来
  • 约数之和可以这样理解:指数的任意一种不同的组合,出来都是N的一个约数,原本是 p 1 0 ∗ p 2 0 + p 1 0 ∗ p 2 1 + p 1 1 ∗ p 2 0 + p 1 1 ∗ p 2 1 p_1^0*p_2^0+p_1^0*p_2^1+p_1^1*p_2^0+p_1^1*p_2^1 p10p20+p10p21+p11p20+p11p21,乘法分配律整理一下就行了

最大公因数

几个基本性质:

  1. d ∣ a , d ∣ b    ⟹    d ∣ a x + b y d\mid a,d \mid b\implies d\mid ax+by da,dbdax+by(读作“d能整除a,d能整除b,d就能整除ax+by”)
  2. a   m o d   b = a − ⌊ a b ⌋ ∗ b = a − c ∗ b a\bmod b=a- \left\lfloor\dfrac{a}{b}\right\rfloor *b=a-c*b amodb=abab=acb

所以 gcd ⁡ ( a , b ) = gcd ⁡ ( b , a − c ∗ b ) = gcd ⁡ ( b , a   m o d   b ) \gcd(a,b)=\gcd(b,a-c*b)=\gcd(b,a\bmod b) gcd(a,b)=gcd(b,acb)=gcd(b,amodb)

第一个等式两边的因数集合是一样的,左边的最大公因数就是右边的最大公因数( d d d 能整除 a a a d d d 能整除 b b b d d d 也就能整除 a − c ∗ b a-c*b acb

任何数都可以整除0,所以 b b b 0 0 0 时就返回 a a a

public static int gcd(int a,int b){
        if(b==0) return a;
        else return gcd(b,a%b);
}

两个数的积等于它们最大公约数和它们最小公倍数的积 a × b = gcd ⁡ ( a , b ) × lcm ⁡ ( a , b ) a\times b=\gcd(a,b)\times\operatorname{lcm}(a,b) a×b=gcd(a,b)×lcm(a,b)

欧拉函数

定义

ϕ ( n ) \phi(n) ϕ(n) 1 ∼ n 1\sim n 1n 中与 n n n 互质的数的个数

ϕ ( 6 ) = 2 \phi(6)=2 ϕ(6)=2

互质: a a a b b b 互质的充要条件是 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1 1 1 1 和任何数都互质

计算方法

n n n 为质数时, ϕ ( n ) = n − 1 \phi(n)=n-1 ϕ(n)=n1

n = p 1 a 1 × p 2 a 2 × p 3 a 3 × ⋯ × p n a n n=p_1^{a_1}\times p_2^{a_2}\times p_3^{a_3}\times \cdots \times p_n^{a_n} n=p1a1×p2a2×p3a3××pnan
ϕ ( n ) = n ∗ ∏ i = 1 x ( 1 − 1 p i ) \phi(n)=n*\prod\limits_{i=1}^x (1-\frac{1}{p_i}) ϕ(n)=ni=1x(1pi1)

简单证明

欧拉函数为积性函数,当 m , n m,n m,n 互质时,有 ϕ ( n m ) = ϕ ( n ) ∗ ϕ ( m ) \phi(nm)=\phi(n)*\phi(m) ϕ(nm)=ϕ(n)ϕ(m)

由唯一分解定理知, n = × p 2 a 2 × p 3 a 3 × ⋯ × p n a n n=\times p_2^{a_2}\times p_3^{a_3}\times \cdots \times p_n^{a_n} n=×p2a2×p3a3××pnan,因此 ϕ ( n ) = ϕ ( p 1 a 1 ) × ϕ ( p 2 a 2 ) ⋯ × ϕ ( p n a n ) \phi(n)=\phi(p_1^{a_1})\times \phi(p_2^{a_2})\cdots\times \phi(p_n^{a_n}) ϕ(n)=ϕ(p1a1)×ϕ(p2a2)×ϕ(pnan)

现考虑 ϕ ( p i a i ) \phi(p_i^{a_i}) ϕ(piai) 的求法,回归到定义,即为小于等于 p i a i p_i^{a_i} piai 的正整数中与其互质的数,从 1 1 1 p i a i p_i^{a_i} piai 一共有 p i a i p_i^{a_i} piai 个数字,其中与 p i a i p_i^{a_i} piai 不互质的有 p i , 2 p i , 3 p i , ⋯   , p i a i − 1 ∗ p i p_i,2p_i,3p_i,\cdots,p_i^{a_i-1}*p_i pi,2pi,3pi,,piai1pi,共 p i a i − 1 p_i^{a_i-1} piai1

所以 ϕ ( p i a i ) = p i a i − p i a i − 1 = p i a i ∗ ( 1 − 1 p i ) \phi(p_i^{a_i})=p_i^{a_i}-p_i^{a_i-1}=p_i^{a_i}*(1-\dfrac{1}{p_i}) ϕ(piai)=piaipiai1=piai(1pi1)

由此得证

求某个值的欧拉函数( O ( n ) O(\sqrt{n}) O(n )):

public static int phi(int a){
        int res = a;
        for(int i=2;i<=a/i;i++){
            if(a%i==0){
                res = res*(i-1)/i;
                while(a%i==0) a/=i;
            }
        }
        if(a>1) res = res*(a-1)/a;
        return res;
}

线性筛求欧拉函数( O ( n ) O(n) O(n)):

public static void getEuler(int n){
        phi[1]=1;
        for(int i=2;i<=n;i++){
            if(!ck[i]){
                primes[++cnt]=i;
                phi[i]=i-1;
            }
            for(int j=1;j<=cnt;j++){
                ck[i*primes[j]]=true;
                if(i%primes[j]==0){
                    phi[i*primes[j]] = phi[i]*primes[j];
                    break;
                }else 
                    phi[i*primes[j]] = phi[i]*(primes[j]-1);
            }
        }
}

模意义下的数和运算

定义: 对于整数 a , b a,b a,b,满足 b > 0 b>0 b>0,则存在唯一的整数 q , r q,r q,r,满足 a = b q + r a=bq+r a=bq+r,其中称 q q q 为商, r r r 为余数

说人话, a ÷ b a\div b a÷b 的商和余数是固定的

这个定义可以将同余式转换为不定方程

模意义下的运算法则

( a + b )   m o d   M = ( a   m o d   M + b   m o d   M )   m o d   M (a+b)\bmod M = (a\bmod M +b\bmod M)\bmod M (a+b)modM=(amodM+bmodM)modM

( a − b )   m o d   M = ( a   m o d   M − b   m o d   M )   m o d   M (a-b)\bmod M = (a\bmod M -b\bmod M)\bmod M (ab)modM=(amodMbmodM)modM

( a × b )   m o d   M = ( a   m o d   M × b   m o d   M )   m o d   M (a\times b)\bmod M = (a\bmod M \times b\bmod M)\bmod M (a×b)modM=(amodM×bmodM)modM
模意义下除法比较特殊

[!summary]
这几个运算法则用人话说就是:

  • 全部加完后再取模等于边加边模
  • 全部减完后再取模等于边减边模
  • 全部乘完后再取模等于边乘边模
  • 全部除完后再取模不等于边除边模

同余

定义:若两数 x , y x,y x,y 除以 b b b 的余数相等,则称 x , y x,y x,y b b b 同余,记做 x ≡ y ( m o d b ) x\equiv y \pmod{b} xy(modb)

重要性质:

  1. 同加性,同乘性,同幂性
  2. x ≡ y ( m o d b ) ⟺ b ∣ ( x − y ) x\equiv y \pmod{b} \Longleftrightarrow b\mid(x-y) xy(modb)b(xy) b b b 能整除 x − y x-y xy

欧拉定理与费马小定理

欧拉定理

a a a n n n 互质,则 a φ ( n ) ≡ 1 ( m o d n ) a^{\varphi (n)} \equiv 1 \pmod{n} aφ(n)1(modn)

费马小定理

p p p质数 a a a p p p 互质,则有 a p − 1 ≡ 1 ( m o d p ) a^{p-1} \equiv 1 \pmod p ap11(modp)

快速幂

二进制思想

public static long qmi(long a,long k,long m){
        long res=1;
        while(k>0){
            if((k&1)==1) res=res*a%m;
            a=a*a%m;
            k>>=1;
        }
        return res;
}

扩展欧几里得算法

裴蜀定理

对于任意正整数 a , b a,b a,b,设他们的最大公约数 gcd ⁡ ( a , b ) = d \gcd(a,b)=d gcd(a,b)=d,则一定存在非零整数 x , y x,y x,y,使得 a x + b y = d ax+by=d ax+by=d

  • d d d a a a b b b 能凑出来的最小正整数
  • 对于整数 a , b , c a,b,c a,b,c a x + b y = c ax+by=c ax+by=c 有整数解当且仅当 gcd ⁡ ( a , b ) ∣ c \gcd(a,b) \mid c gcd(a,b)c

重要推论 a , b a,b a,b 互质的充要条件是存在整数 x , y x,y x,y 使 a x + b y = 1 ax+by=1 ax+by=1

说人话:两个数最小能”凑“出来的正数是他们俩的最大公倍数,并且所有能凑出来的数都是最大公倍数的倍数

这是两个数的情况,裴蜀定理也可以推广到 n n n 个数的情况

扩展欧几里得算法

public static int x,y;
public static int exgcd(int a, int b){
        if(b == 0){
            x = 1;y = 0;
            return a;
        }
        int d = exgcd(b, a % b);
        // 本层 ax1,by1   下一层 x0,y0
        // x1 = y0,y1 = x0-(a/b)*y0
        int temp = x;
        x = y;
        y = temp - a / b * y;
        return d;
}

此时得出的 x 0 , y 0 x_0,y_0 x0,y0 a x + b y = gcd ⁡ ( a , b ) ax+by=\gcd(a,b) ax+by=gcd(a,b) 的一组解,设 x , y x,y x,y 的最小公倍数为 gcd ⁡ ( a , b ) = d \gcd(a,b)=d gcd(a,b)=d,则有:
{ x = x 0 + b d ⋅ k y = y 0 − a d ⋅ k \begin{cases} x=x_0+\dfrac{b}{d}\cdot k\\y=y_0-\dfrac{a}{d}\cdot k\end{cases} x=x0+dbky=y0dak
注意这里的 x , y x,y x,y a x + b y = gcd ⁡ ( a , b ) ax+by=\gcd(a,b) ax+by=gcd(a,b) 的所有解,不是 a x + b y = c ax+by=c ax+by=c 的所有解

如何求 a x + b y = c ax+by=c ax+by=c 的所有解:

  • 先求出 a x + b y = gcd ⁡ ( a , b ) ax+by=\gcd(a,b) ax+by=gcd(a,b) 的一组特解 x 0 , y 0 x_0,y_0 x0,y0
  • 再把 x 0 , y 0 x_0,y_0 x0,y0 一起扩大 c gcd ⁡ ( a , b ) \dfrac{c}{\gcd(a,b)} gcd(a,b)c倍,得到 x 1 , y 1 x_1,y_1 x1,y1
  • 再计算 a x + b y = 0 ax+by=0 ax+by=0 的所有解,即 x = b gcd ⁡ ( a , b ) , y = − a gcd ⁡ ( a , b ) x=\dfrac{b}{\gcd(a,b)},y=-\dfrac{a}{\gcd(a,b)} x=gcd(a,b)b,y=gcd(a,b)a
  • 最后得到 a x + b y = c ax+by=c ax+by=c 的所有解

所以扩展欧几里得算法常用于求解线性同余方程,即给定 a , b , c a,b,c a,b,c,求方程 a x ≡ b ( m o d c ) ax \equiv b \pmod c axb(modc) 的解,等价于求 a x + c y = b ax+cy=b ax+cy=b 的解

逆元

定义:若 a × x ≡ 1 ( m o d p ) a\times x \equiv 1 \pmod p a×x1(modp),则称 x x x a a a 在模 p p p 意义下的乘法逆元,记为 a − 1 ( m o d p ) a^{-1} \pmod p a1(modp)

( a ÷ b )   m o d   M = ( a   m o d   M × b − 1 ( m o d M ) )   m o d   M (a \div b) \bmod M=(a\bmod M \times b^{-1}\pmod M)\bmod M (a÷b)modM=(amodM×b1(modM))modM

如果要分开算的话,才需要这么算,比如 4 ÷ 2 = 2 4\div2=2 4÷2=2,直接用 2 2 2 带入即可

定理: 在大于等于 0 0 0,小于 p p p 的范围内,模 p p p 的逆元(若存在)是唯一的

结论 a a a 在模 p p p 意义下的逆元存在当且仅当 a a a p p p 互质

计算方法

费马小定理

p p p质数 a a a p p p 互质,则 a a a 在模 p p p 意义下的乘法逆元为 a p − 2 a^{p-2} ap2

a p − 2 a^{p-2} ap2 可以用快速幂求解:qmi(a,p-2,p)

扩展欧几里得算法

a × x ≡ 1 ( m o d p ) a\times x \equiv 1 \pmod p a×x1(modp) a x + p y = 1 ax+py=1 ax+py=1 等价:

a × x ≡ 1 ( m o d p ) ⟺ p ∣ ( a x − 1 ) ⟺ ∃ y , 使得 ( a x − 1 ) = p y ⟺ ∃ y , 使得 a x − p y = 1 ⟺ ∃ y , 使得 a x + p y = 1 \begin{aligned}a\times x \equiv 1 \pmod p & \Longleftrightarrow p\mid(ax-1) \\ & \Longleftrightarrow \exists y,\text{使得} (ax-1)=py\\ & \Longleftrightarrow \exists y,\text{使得} ax-py=1 \\ & \Longleftrightarrow \exists y,\text{使得} ax+py=1\end{aligned} a×x1(modp)p(ax1)y,使得(ax1)=pyy,使得axpy=1y,使得ax+py=1

第一步转化是同余的重要性质,第二步转化是模的定义

这个式子是一个关于 a , p a,p a,p 的不定方程,还可以由裴蜀定理发现, a a a 在模 p p p 意义下的逆元当且仅当 gcd ⁡ ( a , p ) = 1 \gcd(a,p)=1 gcd(a,p)=1,即 a a a p p p 互质时才成立

public static int inv(int a,int p){
        exgcd(a, p);
        return x;
}

中国剩余定理

中国剩余定理可以求解下面这样一类同余方程组:
{ x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 )   ⋮ x ≡ a n ( m o d m n ) \begin{cases}x\equiv a_1 \pmod {m_1} \\ x\equiv a_2 \pmod {m_2} \\ \, \quad\vdots \\ x\equiv a_n \pmod {m_n} \end{cases} xa1(modm1)xa2(modm2)xan(modmn)

其中, m 1 , m 2 , ⋯   , m n m_1,m_2,\cdots,m_n m1,m2,,mn 两两互质,则对于任意的整数 a 1 , a 2 , ⋯   , a n a_1,a_2,\cdots,a_n a1,a2,,an 上面这个方程组有解,解的构造方式为:

  • M = ∏ i = 1 n m i M=\prod_{i=1}^nm_i M=i=1nmi,设 M i = M m i M_i=\dfrac{M}{m_i} Mi=miM
  • t i = M i − 1 t_i=M_i^{-1} ti=Mi1 M i M_i Mi m i m_i mi 的逆元(易知 M i M_i Mi m i m_i mi 是互质的,所以逆元一定存在)
  • x x x 的通解为 x = k M + ∑ i = 1 n a i t i M i , k ∈ Z x=kM+\sum_{i=1}^na_it_iM_i,k\in Z x=kM+i=1naitiMi,kZ

组合数学

组合数

C a b C_a^b Cab 代表从 a a a 个物品中选出 b b b 个的方案数(不考虑顺序)

基本计算公式:

C a b = a ! b ! ( b − a ) ! C_a^b=\dfrac{a!}{b!(b-a)!} Cab=b!(ba)!a!

递推求组合数

时间复杂度为 O ( n 2 ) O(n^2) O(n2)

适用范围:

  • 1 ≤ n ≤ 10000 1\le n \le 10000 1n10000
  • 1 ≤ b ≤ a ≤ 2000 1 \le b \le a \le 2000 1ba2000
#include<iostream>
using namespace std;
const int mod = 1e9+7;
long long f[2010][2010];
int main()
{
    //预处理
    for(int i=0;i<=2000;i++)
    {
        for(int j=0;j<=i;j++)
        {
            if(j==0) f[i][j]=1;
            else f[i][j]=(f[i-1][j-1]+f[i-1][j])%mod;
        }
    }
    int n;
    cin>>n;
    while(n--)
    {
        int a,b;
        cin>>a>>b;
        printf("%ld\n",f[a][b]);
    }
}

预处理逆元求组合数

时间复杂度为 O ( a ∗ l o g ( m o d ) ) O(a*log(mod)) O(alog(mod))

适用范围:

  • 1 ≤ n ≤ 10000 1\le n \le 10000 1n10000
  • 1 ≤ b ≤ a ≤ 1 0 5 1 \le b \le a \le 10^5 1ba105

由基本公式得(在模的情况下进行)

C a b = a ! b ! ( b − a ) ! = a ! × b ! − 1 × ( b − a ) ! − 1 C_a^b=\dfrac{a!}{b!(b-a)!}=a!\times b!^{-1}\times (b-a)!^{-1} Cab=b!(ba)!a!=a!×b!1×(ba)!1

image-20230221095651140

static int n,m,k;
static long x,y,z;
static long[] fac,infac;
static final int INF = 0x3f3f3f3f, MOD = (int) 1e9+7;

public static void main(String[] args) throws IOException {
    int lim = (int) 1e5;
    fac = new long[lim+1];
    infac = new long[lim+1];
    fac[0]=infac[0]=1;
    for(int i=1;i<=lim;i++){
        fac[i]=i*fac[i-1]%MOD;
        infac[i]=infac[i-1]*qmi(i,MOD-2,MOD)%MOD;
    }

    n = nextInt();
    for(int i=1;i<=n;i++){
        int a =nextInt(),b = nextInt();
        long res = fac[a]*infac[b]%MOD*infac[a-b]%MOD;
        cout.println(res);
    }
    cout.flush();
}// End of main

public static long qmi(long a,long k,long p){
    long res = 1;
    while(k>0){
        if((k&1)==1) res = res*a%p;
        a = a*a%p;
        k>>=1;
    }
    return res;
}

Lucas定理求组合数

C a b ≡ C a p b p ⋅ C a   m o d   p b   m o d   p ( m o d p ) C_a^b\equiv C_{\frac{a}{p}}^{\frac{b}{p}} \cdot C_{a \bmod p}^{b \bmod p} \pmod p CabCpapbCamodpbmodp(modp)

适用范围:

  • 1 ≤ n ≤ 20 1\le n \le 20 1n20
  • 1 ≤ b ≤ a ≤ 1 0 18 1 \le b \le a \le 10^{18} 1ba1018
  • 1 ≤ p ≤ 1 0 5 1\le p \le 10^5 1p105

[!important]
long 类型的读入最好用 Scanner,要不然你咋挂的都不知道

static int n,m,k;
static long x,y,z;
static long[] fac,infac;
static final int INF = 0x3f3f3f3f, MOD = (int) 1e9+7;

public static void main(String[] args) throws IOException {
    Scanner cin = new Scanner(System.in);
    n = cin.nextInt();
    while(n-->0){
        long a = cin.nextLong(),b = cin.nextLong(),p=cin.nextLong();
        cout.println(lucas(a, b, p));
    } 
    cout.flush();
}// End of main

public static long lucas(long a,long b,long p){
    if(a<p && b<p) return C(a,b,p);
    // a%p后肯定是<p的,所以可以用C(),但a/p后不一定<p 所以用lucas继续递归
    return lucas(a/p, b/p, p)*C(a%p,b%p,p)%p;
}

public static long C(long a,long b,long p){
	long res = 1;
	// C_a^b 的公式求法就是
	// a!/(b!(a-b)!) = (a-b+1)*...*a / b! 分子有b项
	// i -> 1 - b    j -> a - a-b+1 
	for(long i=1,j=a;i<=b;i++,j--){
		res = res*j%p;
		res = res*qmi(i,p-2,p)%p;
	}
	return res;
}

public static long qmi(long a,long k,long p){
    long res = 1;
    while(k>0){
        if((k&1)==1) res = res*a%p;
        a = a*a%p;
        k>>=1;
    }
    return res;
}

卡特兰数

6828_9476d97655-Catalan

卡特兰数计算公式:

C 2 n n − C 2 n n − 1 = C 2 n n n − 1 C_{2n}^n-C_{2n}^{n-1}=\dfrac{C_{2n}^n}{n-1} C2nnC2nn1=n1C2nn
image-20230221144014759

f ( n ) = f ( 0 ) f ( n − 1 ) + f ( 1 ) f ( n − 2 ) + + f ( n − 1 ) f ( 0 ) f(n) = f(0)f(n-1) + f(1)f(n-2) + + f(n-1)f(0) f(n)=f(0)f(n1)+f(1)f(n2)++f(n1)f(0)

1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862,

应用:

  • 出栈次序
  • n对括号正确匹配数目
  • 给定节点组成二叉搜索树
  • 在圆上选择 2 n 2n 2n 个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数
  • 求一个凸多边形区域划分成三角形区域的方法数

期望

在OI中,期望一般指的就是达到结果的期望,最朴素的计算是每次可能结果的概率乘以其结果的总和

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/599462.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第3章“程序的机器级表示”:控制

文章目录 3.6 控制3.6.1 条件码3.6.2 访问条件码3.6.3 跳转指令及其编码3.6.4 翻译条件分支3.6.5 循环do-while 循环while循环for循环 3.6.6 switch 语句 3.6 控制 截止目前&#xff0c;考虑了 访问数据和 操作数据 的方法。程序执行的另一个很重要的部分就是控制被执行操作的…

Maven高级5-私服

1. 简介 一台独立的服务器&#xff0c;用于解决团队内部的资源共享与资源同步问题&#xff08;模拟了中央服务器&#xff09;&#xff1b; https://help.sonatype.com/repomanager3/download 命令行启动服务器 在nexus.exe目录&#xff08;bin目录&#xff09;下启动cmd&#…

【认知提升思维篇】之 反刍思维--恶性思考的根源

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;普本…

代码随想录算法训练营第五十一天 | 力扣 309.最佳买卖股票时机含冷冻期, 714.买卖股票的最佳时机含手续费

309.最佳买卖股票时机含冷冻期 题目 309. 最佳买卖股票时机含冷冻期 给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买卖一…

Vulnhub | 实战靶场渗透测试 - PRIME: 1

0x00 免责声明 本文仅限于学习讨论与技术知识的分享&#xff0c;不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;本文作者不为此承担任何责任&#xff0c;一旦造成后果请自行承担…

“本草”大模型开源,ChatGPT时代,连AI私人医生都出现了?

大家好,我是千与千寻,也可以叫我千寻,今天给大家分享的ChatGPT新应用项目,是ChatGPT模型在医学领域的应用,什么,医学领域? 是的,没错,是医学领域的ChatGPT应用,我们都知道ChatGPT是OpenAI开源的一个智能对话式引擎,今天给大家分享的项目叫“本草”。 “本草”模型是…

IIC协议与OLED

1.认识OLED 1、OLED概述&#xff1a; OLED&#xff08;Organic Light-Emitting Diode&#xff0c;有机发光二极管&#xff09;是一种显示技术&#xff0c;利用有机材料的发光特性来产生光。OLED显示器由一系列有机材料层组成&#xff0c;当电流通过时&#xff0c;这些材料会发…

【性能调优】真实体验 “系统调用是重开销”

实践背景是开发云原生背景下的指纹识别插件&#xff0c;主要针对的是镜像、容器等云时代的软件资产。 信息安全语境下的 指纹识别 指的是定位软件的特征&#xff0c;如名称、版本号、开源许可证等&#xff0c;就像指纹是人的独特生物凭证&#xff0c;这些特征是软件的独特电子凭…

六一儿童节 全网最全的微服务+Outh2套餐,你确定不来试一试?(入门到精通,附源码)满足你的味蕾需要(二)

咱们废话不多说&#xff0c;直接开干&#xff01;&#xff01;&#xff01; 目录 一、项目目录 二、Token 三、授权服务器oauth 1.pom 2.application 3.OauthApp启动类 4.DiyUserDetails 5.MyUserDetailService 6.KeyPairController 7.TokenConfig 8.WebSecurityCo…

LNMP架构

LNMP架构 一、LNMP架构原理二、LNMP部署1、安装 Nginx 服务1.安装依赖包2.创建运行用户3.编译安装4.优化路径5.添加 Nginx 系统服务 2、安装 MySQL 服务1.安装Mysql环境依赖包2.创建运行用户3.编译安装4.修改mysql 配置文件5.更改mysql安装目录和配置文件的属主属组6.设置路径环…

电子模块|压力传感器模块HX711---硬件介绍

电子模块|压力传感器模块HX711---硬件介绍与C51&&STM32驱动 实物照片模块简介模块特点 硬件模拟输入供电电源时钟选择串口通讯复位和断电HX711相关部分的 PCB 设计 实物照片 模块简介 HX711是一款专为高精度称重传感器而设计的24位A/D转换器芯片。与同类型其它芯片相比…

后端接口调式工具

后端接口调式工具 目录概述需求&#xff1a; 设计思路实现思路分析1.Postman2.Swagger 文档测试工具3.Sniff 文档测试工具4.APIpost 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardne…

【SCADA】启动KingSCADA运行系统,提示加载报警库服务失败?

大家好&#xff0c;我是雷工&#xff01; 今天启动KingSCADA时&#xff0c;发现无法运行&#xff0c;提示“加载 报警库服务 失败”&#xff0c;现将问题排查及解决问题的过程记录如下。 一、问题描述&#xff1a; 1、提示如下图&#xff1a; 2、信息窗口提示&#xff1a; …

性能测试从零开始落地实施全过程指南之性能测试计划怎么写?

目录 前言 一、测试背景 二、测试目的 三、测试范围 四、术语约定 五、环境说明 六、需求分析 七、测试策略 八、准备工作 九、组织架构 十、风险分析 十一、交付清单 十二、阶段进度 前言 最近有些同学找我咨询关于性能测试计划相关的问题&#xff0c;原因是他们…

《C++ list的模拟实现》

本文主要介绍list容器的模拟实现 文章目录 1、迭代器正向迭代器类反向迭代器类 2、push_back尾插函数3、 push_front头插函数4、 insert插入函数5、erase删除函数6、pop_front函数7、pop_back函数8、 构造函数9、 拷贝构造函数10、 list赋值重载函数11、clear12、 析构函数程序…

AI注册流程

1、首先需要有一个OpenAI账号&#xff0c;如果有方法的&#xff0c;就可以自己先注册一下。如果没有方法的&#xff0c;还有一个付费版本的可以备选&#xff0c;亲测可用。 2、注册建议使用谷歌账号关联登录&#xff0c;最方便。微软账号太慢了&#xff0c;也可以使用。注册使用…

SAP-MM库存进销存报表

1、总览&#xff1a; 事务代码MB5B是查询选择期间之内的收发存报表&#xff1b; 其中&#xff0c;收、发为汇总选择期间的收、发信息&#xff0c;存为选择期间的期初、期末库存数据&#xff1b;我们也可以用该报表查询历史上某一天的库存&#xff0c;但注意有一些限制条件。 …

【Selenium】提高测试爬虫效率:Selenium与多线程的完美结合

前言 使用Selenium 创建多个浏览器&#xff0c;这在自动化操作中非常常见。 而在Python中&#xff0c;使用 Selenium threading 或 Selenium ThreadPoolExecutor 都是很好的实现方法。 应用场景&#xff1a; 创建多个浏览器用于测试或者数据采集&#xff1b;使用Selenium…

Region Proposal Network (RPN) 架构详解

动动发财的小手&#xff0c;点个赞吧&#xff01; 简介 如果您正在阅读这篇文章[1]&#xff0c;那么我假设您一定听说过用于目标检测的 RCNN 系列&#xff0c;如果是的话&#xff0c;那么您一定遇到过 RPN&#xff0c;即区域提议网络。如果您不了解 RCNN 系列&#xff0c;那么我…

Github copilot的详细介绍,竞品比对分析,效率使用方法总结。

Copilot介绍&#xff0c;与竞品对比 Copilot是GitHub和OpenAI合作开发的一款人工智能代码助手&#xff0c;它可以根据用户输入的注释和代码片段&#xff0c;自动生成高质量的代码。Copilot使用了OpenAI的GPT模型&#xff0c;可以学习和理解大量的代码库和文档&#xff0c;从而…