算法提高 组合公式求值
时间限制:1.0s 内存限制:256.0MB
问题描述
给定n, m,求:
输入格式
输入一行,包含两个整数n, m。
输出格式
输出一行,包含求得的值,由于答案可能非常大,请输出此公式除以987654321的余数。
样例输入
3 1
样例输出
162
数据规模和约定
1<=m<=n<=10^7。
package com.sihai.improve;
import java.math.BigInteger;
import java.util.Scanner;
class Number {
long x,y,dd;
/**
* @param x
* @param y
* @param dd
*/
public Number(long x, long y, long dd) {
super();
this.x = x;
this.y = y;
this.dd = dd;
}
public Number() {
super();
}
}
public class Main {
static BigInteger n, m;
static int k;
static long monum = 999101;
static BigInteger mobig = new BigInteger("999101");
static BigInteger big2 = new BigInteger("2");
static long ansnum1,ans;
static long dp[][], bignum[], subnum[];
static long fact[];
private static Number gcd(long a,long b) {
if (b==0) return new Number(1,0,a);
Number number=gcd(b, a%b);
long x=number.y;
long y=number.x-(a/b)*number.y;
long dd=number.dd;
return new Number(x,y,dd);
}
private static long mod_inverse(long num) {
if (num==0) return 0;
Number number=gcd(num, monum);
long x=(number.x+monum)%monum;
return x;
}
private static long cal(BigInteger num) {
if (num.equals(BigInteger.ZERO)) return 1;
if (num.equals(BigInteger.ONE)) return 2;
long mnum = cal(num.divide(big2));
mnum = mnum*mnum%monum;
BigInteger mo = num.mod(big2);
if (mo.equals(BigInteger.ONE))
mnum=mnum*2%monum;
return mnum;
}
private static void init() {
fact = new long[(int) (monum + 1)];
fact[0] = 1;
for (int i = 1; i <= monum; i++)
fact[i]=(fact[i-1]*(long)i)%monum;
}
private static long calc(int n,int m) {
if (n<m) return 0;
long mo=fact[m]*fact[n-m]%monum;
long divnum=mod_inverse(mo);
long res=fact[n]*divnum%monum;
return res;
}
private static long lucas(BigInteger n,BigInteger m){
if (m.equals(BigInteger.ZERO)) return 1;
int nmo=n.mod(mobig).intValue();
int mmo=m.mod(mobig).intValue();
return calc(nmo, mmo)*lucas(n.divide(mobig),m.divide(mobig))%monum;
}
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
n = reader.nextBigInteger();
m = reader.nextBigInteger();
k = reader.nextInt();
BigInteger kbig=new BigInteger(String.valueOf(k));
dp = new long[k + 1][k + 1];
dp[0][0]=1;
long mon=n.mod(mobig).longValue();
for (int i = 0; i <= k - 1; i++)
for (int j = 0; j <= i; j++) {
dp[i + 1][j] = (dp[i+1][j]+(long)j*dp[i][j])%monum;
dp[i + 1][j + 1] =(dp[i+1][j+1]+(long)(mon-j+monum)*dp[i][j])%monum;
}
long mulnum =cal(n.subtract(kbig));
for (int i = k; i >= 0; i--) {
ansnum1 =(ansnum1+dp[k][i]*mulnum)%monum;
mulnum = (mulnum*2)%monum;
}
init();
ans=ansnum1*lucas(n, m)%monum;
System.out.println(ans);
}
}
<script type="text/javascript">
$(function () {
$('pre.prettyprint code').each(function () {
var lines = $(this).text().split('\n').length;
var $numbering = $('<ul/>').addClass('pre-numbering').hide();
$(this).addClass('has-numbering').parent().append($numbering);
for (i = 1; i <= lines; i++) {
$numbering.append($('<li/>').text(i));
};
$numbering.fadeIn(1700);
});
});
</script>
分享到:
相关推荐
【知识点详解】 1. **等差数列求和**: 在"煤球数目"问题中,煤球的每一层都是一个等...以上分析涵盖了Java编程中常见的算法思维、数学建模和编程技巧,这些问题的解答对于提升编程能力、解决实际问题具有重要意义。
【标题】"Blue-Bridge-10th-java-B-2.rar_BLUE" 提供的是蓝桥杯编程竞赛第10届Java B组的部分题目代码参考,主要涵盖了第5至第9题。这些题目是针对初学者到进阶者设计的,旨在提升参赛者的Java编程能力,包括算法...
练习2-18 求组合数 (15 分) 本题要求编写程序,根据公式Cnm=m!(n−m)!n!算出从n个不同元素中取出m个元素(m≤n)的组合数。 建议定义和调用函数fact(n)计算n!,其中n的类型是int,函数类型是...
- 组合数学:排列组合、递推公式、鸽巢原理等。 - 数论:质因数分解、模运算、中国剩余定理。 - 广义欧几里得算法:求最大公约数和扩展欧几里得算法。 6. **逻辑思维与问题解决**: - 熟练阅读题目,理解题目...
【标题】"lanqiaobei.rar_lanqiaobei_蓝桥杯java"是一个与蓝桥杯编程竞赛相关的压缩文件,其中包含了用于训练Java编程技能的练习题目。蓝桥杯是一项广受欢迎的全国性编程竞赛,旨在提升参赛者的算法设计和编程能力。...
### 2012第三届蓝桥杯全国软件设计大赛Java本科组预赛试题解析 #### 结果填空题解析 **1. 黄金分割数与鲁卡斯数列** - **背景介绍**:黄金分割数(Golden Ratio)通常用希腊字母φ表示,是一个数学上的常数,其值...
4. 低碳生活大奖赛计分规则:这是一个组合数学问题。选手答对或答错问题会影响其分数,根据得分推断答题情况。解答此题需要考虑所有可能的得分路径,并确保最终得分是100分。通过穷举所有可能的答题情况,形成只含1...
### 第七届蓝桥杯Java B组试题解析 #### 1. 煤球数目(3分) **题目描述:** 题目要求计算一个由100层构成的三角棱锥形煤球堆的总煤球数量。每层的煤球数量形成一个序列,第n层的煤球数量为1到n的累加和。 **分析...
黄金分割数(1.618...)是一个重要的数学常数,可以通过递归公式计算。给定的问题要求100位精度的黄金分割数。在Java中,可以使用BigDecimal类处理高精度计算。利用黄金分割数的定义1 + 1/(1 + 1/(1 + 1/x)),通过...
然而,考虑到蓝桥杯竞赛的一般性质和以往比赛的题目类型,我们可以推测可能涉及到的IT知识点,这包括但不限于编程语言(如C、C++、Java、Python等)、算法设计、数据结构、计算机网络、操作系统原理、数据库原理等。...
- **递推公式**: dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + matrix[i][j](当 i 和 j 都大于 0 时),其中 matrix[i][j] 是原矩阵中的值。 - **边界条件**: dp[0][0] = matrix[0][0],对于第一行和第一列的其他...
"蓝桥杯省赛"是一项针对信息技术和编程能力的竞赛,旨在提高大学生和中学生的编程技能及创新思维。第五届蓝桥杯省赛的题目涵盖了多种编程语言和算法问题,为参赛者提供了丰富的挑战。 在这样的比赛中,参赛者通常会...
假设已经有了一个递归函数`generateCombinations`用于生成组合,这里给出如何调用该函数的基本框架: ```java public class Main { public static void main(String[] args) { char[] athletes = {'A', 'B', 'C', ...
### 关于蓝桥杯C++的一些相关资源 #### 第五届蓝桥杯C++竞赛概述 蓝桥杯是一项面向全国的大型IT类专业赛事,旨在检验参赛者的编程能力及解决问题的能力。第五届蓝桥杯C++竞赛是其中的一个重要组成部分,为编程爱好...
题目给出了两种不同的解决方案:一种是基于深度优先搜索(DFS)的方法,另一种则是利用组合数学中的卡特兰数(Catalan Number)公式。 1. **深度优先搜索(DFS)方法**: - 定义全局变量`count`记录可能的次序数量...
综上所述,蓝桥杯软件类赛真题(JavaB组)涵盖的考点范围广泛,不仅包括了Java编程语言的熟练应用,还包括了算法思维、数据结构的合理运用以及对数学概念的深入理解。参赛者在准备此类竞赛时,需要通过系统学习和...
设i岁开始过生日,共过了k年,那么吹熄蜡烛的总数可以表示为等差数列求和公式(2*i+k)*(k+1)/2,解题思路是使用两个嵌套的for循环穷举i和k的可能值(1-100范围内),找到满足(2*i+k)*(k+1) == 472的i和k值。...