公式求值

输入n, m, k,输出图1所示的公式的值。其中C_n^m是组合数,表示在n个人的集合中选出m个人组成一个集合的方案数。组合数的计算公式如图2所示。

输入的第一行包含一个整数n;第二行包含一个整数m,第三行包含一个整数k。

计算图1所示的公式的值,由于答案非常大,请输出这个值除以999101的余数。

【样例输入1】

3

1

3

【样例输出1】

162

【样例输入2】

20

10

10

【样例输出2】

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的数据;

资源约定:

峰值内存消耗(含虚拟机) < 128M

CPU消耗 < 2000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。

注意:主类的名字必须是:Main,否则按无效代码处理。







这道题附上一个思路方便读者了解

Lucas定理加上一些数学处理转换。直接给大家个链接吧http://tieba.baidu.com/p/2832505865。重点可以看看

十四楼对这道题的处理方法,还是不太懂的话可以草稿纸上演算演算。注意dp[i][j]代表第i次求导后(xj)*(1+x)(n-j)的系数。然后具体写代码的时候,方法返回类型尽量处理为long,能取模就取模,尽量少用大数直接加减乘除运算操作,不然后面的数据会超时(我一开始就直接用大数写,最后两个点超时了,前面几个点也比较灵异地出现了错误答案)。其他标程逆元部分似乎是利用费马小定理,然后a^(p-2)模p为a模p的逆元,而我是直接利用扩展欧几里得求a模p的逆元。对了,还要注意lucas定理利用时,如果c(n%p,m%p)中n%p<m%p,则值应直接返回0而不是1(这就是那个测试点的问题所在)

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();
// TODO Auto-generated constructor stub
} }
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) {
// TODO Auto-generated method stub
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);
} }

java实现第四届蓝桥杯公式求值的更多相关文章

  1. Java实现第十届蓝桥杯数列求值

    试题 C: 数列求值 本题总分:10 分 [问题描述] 给定数列 1, 1, 1, 3, 5, 9, 17, -,从第 4 项开始,每项都是前 3 项的和.求 第 20190324 项的最后 4 位数 ...

  2. java实现第四届蓝桥杯剪格子

    剪格子 题目描述 如图p1.jpg所示,3 x 3 的格子中填写了一些整数. 我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60. 本题的要求就是请你编程判定:对给定的m x n 的格子 ...

  3. java实现第四届蓝桥杯逆波兰表达式

    逆波兰表达式 正常的表达式称为中缀表达式,运算符在中间,主要是给人阅读的,机器求解并不方便. 例如:3 + 5 * (2 + 6) - 1 而且,常常需要用括号来改变运算次序. 相反,如果使用逆波兰表 ...

  4. java实现第四届蓝桥杯黄金连分数

    黄金连分数 题目描述 黄金分割数0.61803- 是个无理数,这个常数十分重要,在许多工程问题中会出现.有时需要把这个数字求得很精确. 对于某些精密工程,常数的精度很重要.也许你听说过哈勃太空望远镜, ...

  5. java实现第四届蓝桥杯危险系数

    危险系数 抗日战争时期,冀中平原的地道战曾发挥重要作用. 地道的多个站点间有通道连接,形成了庞大的网络.但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系. 我们来定义一个危险系数DF( ...

  6. java实现第四届蓝桥杯阶乘位数

    阶乘位数 题目描述 如图p1.jpg所示,3 x 3 的格子中填写了一些整数. 我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60. 本题的要求就是请你编程判定:对给定的m x n 的格 ...

  7. java实现第四届蓝桥杯大臣的旅费

    大臣的旅费 题目描述 很久以前,T王国空前繁荣.为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大 ...

  8. java实现第四届蓝桥杯梅森素数

    梅森素数 题目描述 如果一个数字的所有真因子之和等于自身,则称它为"完全数"或"完美数" 例如:6 = 1 + 2 + 3 28 = 1 + 2 + 4 + 7 ...

  9. java实现第四届蓝桥杯买不到的数目

    买不到的数目 题目描述 小明开了一家糖果店.他别出心裁:把水果糖包成4颗一包和7颗一包的两种.糖果不能拆包卖. 小朋友来买糖的时候,他就用这两种包装来组合.当然有些糖果数目是无法组合出来的,比如要买 ...

随机推荐

  1. [Vue warn]: Missing required prop: "value"

    tips vue中遇到这个问题 真的是很苦恼 一点一点排查 ,最后发现是因为我在 select的option中写了个默认值 ,所以才报这个错误 注释:去掉默认值那个option 选项就不报错了

  2. 【5min+】美化API,包装AspNetCore的返回结果

    系列介绍 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net ...

  3. shell 光标处理快捷键

    Ctrl+左右键 单词之间跳转Ctrl+a跳到本行的行首, Ctrl+e则跳到页尾. Ctrl+u删除当前光标前面的文字 ctrl+k-删除当前光标后面的文字 Ctrl+w和Alt+d-对于当前的单词 ...

  4. ql的python学习之路-day8

    前言:本节主要学习的是函数的全局变量和局部变量以及递归 一.全局变量和局部变量 定义在函数外并且在函数头部的变量,叫做全局变量,全局变量在整个代码中都生效. 局部变量只在函数里生效,这个函数就叫做这个 ...

  5. How to create a angular2 project process

    步骤1. 设置开发环境 在开始工作之前,我们必须设置好开发环境. 如果你的机器上还没有Node.js®和npm 和VScode(因为我是用VS工具来编辑的), 请先安装它们. 然后全局安装 Angul ...

  6. P1251 餐巾计划问题 网络流

    P1251 餐巾计划问题 #include <bits/stdc++.h> using namespace std; typedef long long ll; , inf = 0x3f3 ...

  7. P4525 【模板】自适应辛普森法1

    P4525 [模板]自适应辛普森法1 #include <bits/stdc++.h> using namespace std; ; double a, b, c, d, l, r; in ...

  8. java遇到的error解决

    解决Cannot change version of project facet Dynamic web module to 2.5 maven 不能设置为web3.0人解决方法 http://www ...

  9. 【Java】面试官灵魂拷问:if语句执行完else语句真的不会再执行吗?

    写在前面 最近跳槽找工作的朋友确实不少,遇到的面试题也是千奇百怪,这不,一名读者朋友面试时,被面试官问到了一个直击灵魂的问题:if 语句执行完else语句真的不会再执行吗?这个奇葩的问题把这名读者问倒 ...

  10. Linux文件列表查询ll和ls区别

    ll ll查询文件列表,查询结果为当前目录下文件和文件夹的详细信息,包括权限.根目录.用户.创建时间等. ls ls查询出的查询结果只显示当前目录下文件夹和文件名称