• 公式求值


    问题描述
      输入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)项的公式,然后分别求这两类公式的值,均有快速方法。最终将这些项组合起来得到答案。
    代码:
    import java.math.BigInteger;
    import java.util.Scanner;
    
    public class Main {
        private static Scanner sc = new Scanner(System.in);
        private static long Mo = 999101;
        private static BigInteger Mod = new BigInteger("999101");
        private static long [] f = new long[999101];
        private static long [][] dp = new long[1001][1001];
        private static long Lucas(BigInteger n,BigInteger m) {
            long ans = 1;
            while(!n.equals(BigInteger.ZERO) && !m.equals(BigInteger.ZERO)) {
                ans = ans * C(n.mod(Mod).intValue(),m.mod(Mod).intValue()) % Mo;
                n = n.divide(Mod);
                m = m.divide(Mod);
            }
            return ans;
        }
        private static long C(int n,int m) {
            if(n < m) return 1;//第四个测试数据
            long ans = f[n] % Mo;
            ans = ans * pow(f[m],BigInteger.valueOf(Mo - 2)) % Mo;
            ans = ans * pow(f[n - m],BigInteger.valueOf(Mo - 2)) % Mo;
            return ans;
        }
        private static long pow(long a,BigInteger b) {
            long d = 1;
            BigInteger two = new BigInteger("2");
            while(!b.equals(BigInteger.ZERO)) {
                if(b.mod(two).equals(BigInteger.ONE)) d = d * a % Mo;
                a = a * a % Mo;
                b = b.divide(two);
            }
            return d;
        }
        private static void init(long n,int k) {
            f[0] = 1;
            for(int i = 1;i < Mo;i ++) {
                f[i] = f[i - 1] * i % Mo;
            }
            dp[0][0] = 1;
            for(int i = 0;i < k;i ++) {
                for(int j = 0;j <= i;j ++) {
                    dp[i + 1][j] = (dp[i + 1][j] + dp[i][j] * j) % Mo;
                    dp[i + 1][j + 1] = (dp[i + 1][j + 1] + (n - j) * dp[i][j]) % Mo;
                }
            }
        }
        public static void main(String[] args) {
            BigInteger n = sc.nextBigInteger();
            BigInteger m = sc.nextBigInteger();
            int k = sc.nextInt();
            init(n.mod(Mod).intValue() + Mo,k);
            long ans = 0;
            long p = pow(2,n);
            for(int i = 0;i <= k;i ++) {
                ans = (ans + dp[k][i] * p) % Mo;
                p = (Mo + 1) / 2 * p % Mo;
            }
            ans = ans * Lucas(n,m) % Mo;
            System.out.println(ans);
        }
    }
  • 相关阅读:
    css中的背景、渐变 文本格式化和表格的常用属性
    HTML5中常见的英文单词
    matlab文件处理
    优先级队列
    编程珠玑(一)
    排序算法之希尔排序
    自己写的矩阵类Matrix
    排序算法之快速排序
    Thoughtworks公司面试题——MARS ROVERS问题
    matlab画图
  • 原文地址:https://www.cnblogs.com/8023spz/p/10394814.html
Copyright © 2020-2023  润新知