Acwing---887. 求组合数 III (Java)_数学知识_Lucas定理

原题链接

①. 题目

在这里插入图片描述

②. 思路

在这里插入图片描述

在这里插入图片描述在这里插入图片描述

时间复杂度分析

在这里插入图片描述

③. 学习点

Lucas定理

④. 代码实现

import java.util.Scanner;

public class Main {
    
    
	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int n=sc.nextInt();
		long a,b,p;
		while(n-->0) {
    
    
			a=sc.nextLong();
			b=sc.nextLong();
			p=sc.nextLong();
			System.out.println(lucas(a,b,p));
		}
	}
	//快速幂求次方
	static long quickPower(long a,long b,long p) {
    
    
		long res=1;
		while(b>0) {
    
    
			if((b&1)==1) {
    
    
				res=res*a%p;
			}
			a=a*a%p;
			b>>=1;
		}
		return res;
	}
	
	//求组合数 利用函数公式
	static long combination(long a,long b,long p) {
    
    
		long res=1;
		for (long i =1,j=a;i<=b;i++,j--) {
    
    
			res=res*j%p; //a*(a-1)*(a-2)....*(a-b+1)
			res=res*quickPower(i, p-2, p)%p; //快速幂求b的阶乘的逆元
		}
		return res;
	}
	
	static long lucas(long a,long b,long p) {
    
    
		if(a<p&&b<p) {
    
    
			return combination(a, b, p);
		}
		return combination(a%p, b%p, p)*lucas(a/p, b/p, p)%p; //根据lucas公式递归将a b的值缩小
	}

}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45480785/article/details/113896620