蓝桥杯2013决赛JAVA本科B组试题

  • 格式:doc
  • 大小:152.50 KB
  • 文档页数:11

下载文档原格式

  / 11
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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.}