蓝桥杯2013决赛JAVA本科B组试题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
试题一:公式求值
问题描述
输入n, m, k,输出下面公式的值。
其中C_n^m是组合数,表示在n个人的集合中选出m个人组成一个集合的方案数。组合数的计算公式如下。
输入格式
输入的第一行包含一个整数n;第二行包含一个整数m,第三行包含一个整数k。
输出格式
计算上面公式的值,由于答案非常大,请输出这个值除以999101的余数。
样例输入
3
1
3
样例输出
162
样例输入
20
10
10
样例输出
359316
数据规模和约定
对于10%的数据,n≤10,k≤3;
对于20%的数据,n≤20,k≤3;
对于30%的数据,n≤1000,k≤5;
对于40%的数据,n≤10^7,k≤10;
对于60%的数据,n≤10^15,k ≤100;
对于70%的数据,n≤10^100,k≤200;
对于80%的数据,n≤10^500,k ≤500;
对于100%的数据,n在十进制下不超过1000位,即1≤n<10^1000,1≤k≤1000,同时0≤m≤n,k≤n。
提示
999101是一个质数;
当n位数比较多时,绝大多数情况下答案都是0,但评测的时候会选取一些答案不是0的数据;
通过推导,可以将原式变为一个只含2^(n-i)的项和C(n,m)项的公式,然后分别求这两类公式的值,均有快速方法。最终将这些项组合起来得到答案。
1.import java.math.BigInteger;
2.import java.util.Scanner;
3.public class Main
4.{
5.public static BigInteger lucas(BigInteger n,BigInteger m,BigInteger p
){
6.if(m.equals(BigInteger.ZERO)) return BigInteger.ONE;
7.return BigInteger.valueOf(f(n.mod(p).longValue(),m.mod(p).longValue())).mu
ltiply(lucas(n.divide(p),m.divide(p),p)).mod(p);
8.}
9.
10.
11.public static long f(long n,long m){
12.if(m>n) return 1;
13.if(n==m|| m==0) return 1;
14.if(m>n-m) m=n-m;
15.long tmpi=1,tmpn=1,s1=1,s2=1,ans=1;
16.for (int i = 1; i<=m; i++) {
17.tmpi=i;
18.tmpn=n-i+1;
19.s1=s1*tmpi%999101;
20.s2=s2*tmpn%999101;
21.}
22.ans = s2*pow1(s1,999099)%999101;
23.return ans%999101;
25.public static long pow1(long x,long n) {
26.if(x==1) return 1;
27.if (n==0)
28.return 1;
29.else {
30.while ((n & 1)==0) {
31.n>>=1;
32.x=(x *x)%999101;
33.}
34.}
35.long result = x%999101;
36.n>>=1;
37.while (n!=0) {
38.x=(x *x)%999101;;
39.if ((n & 1)!=0)
40.result =result*x%999101;
41.n>>=1;
42.}
43.return result;
44.}
45.public static void main(String[] args) {
46.Scanner sc = new Scanner(System.in);
47.BigInteger n = new BigInteger(sc.nextLine());
48.BigInteger m = new BigInteger(sc.nextLine());
49.int k = Integer.parseInt(sc.nextLine());
50.long start = System.currentTimeMillis();
51.BigInteger md = new BigInteger("999101");
52.long Cnm=lucas(n, m,md).longValue()%999101;
53.long sum = 0;
54.if(Cnm!=0){
55.int[][] a = new int[k][k];
56.int h = 1;
57.for (int i = 0; i < k; i++) {
58.for (int j = 0; j < k; j++) {
59.if (j >= h)
60.a[i][j] =0;
61.else {
62.if (j == 0 || j == h - 1)
63.a[i][j] = 1;
64.else {
65.a[i][j] = (a[i - 1][j - 1]*(h - j)+a[i - 1][j])%999101;
66.}
67.}