Acwing---886. 求组合数 II (Java)_数学知识_快速幂求逆元_预处理组合公式

原题链接

①. 题目

在这里插入图片描述

②. 思路

在这里插入图片描述

时间复杂度分析

这道题的时间复杂度为O(n),n为题目中的询问个数
在这里插入图片描述

③. 学习点

快速幂求逆元阶乘

④. 代码实现

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    
    
	static int N=100010,p=(int)1e9+7;
	static int[] fact=new int[N],infact=new int[N];
	
	public static void main(String[] args) throws Exception {
    
    
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int t = Integer.parseInt(br.readLine());
		fact[0] = infact[0] = 1;  //初始化
		for (int i = 1; i <N; i++) {
    
    
			fact[i]=(int)((long)fact[i-1]*i%p);  //递归求i的阶乘
			infact[i]=(int)((long)infact[i-1]*qmi(i,p-2,p)%p); //费马小定理求i的逆元阶乘
		}
		while(t-->0) {
    
    
			String[] s = br.readLine().split(" ");
			int a=Integer.parseInt(s[0]);
			int b=Integer.parseInt(s[1]);
			//直接套用组合数模板求解
			int res=(int)((long)fact[a]*infact[a-b]%p*infact[b]%p);
			System.out.println(res);
		}
	}
	//快速幂预处理 a^k%p  将k拆成二进制
	static int qmi(int a,int k,int p) {
    
    
		long res=1;
		while(k>0) {
    
    
			if((k&1)!=0)res=res*a%p;
			a=(int)((long)a*a%p);
			k>>=1;
		}
		return (int)res;
	}

}

在这里插入图片描述

猜你喜欢

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