参考答案: import java.util.Scanner;
public class Gongshi{
public static void main(String[] args) {
Scanner C=new Scanner(System.in);
long n=C.nextInt();
long m=C.nextInt();
long k=C.nextInt();
long p=0;
long h=zh(m,n);
//System.out.println(h);
for(int i=0;i<=n;i++){
p+=zh(i,n)*ik(i,k);
}
System.out.println((p*h)%999101);
}
public static long jc(long j){ //求j的阶乘
long sum=1;
for(int i=1;i<=j;i++){
sum*=i;
}
return sum;
}
public static long zh(long a,long b){ //求组合数c(b,a)
long t=jc(b)/(jc(a)*jc(b-a));
return t;
}
public static long ik(long x,long y){ //求x的y次方
long q=1;
for(int p=0;p
q*=x;
}
return q;
}
}我的代码 1:初稿import java.util.Scanner;
public class Result {
public static void main(String[] args) {
Scanner sca=new Scanner(System.in);
int n,m,k,sum=0,h;
n=sca.nextInt();
m=sca.nextInt();
k=sca.nextInt();
for(int i=1;i<=n;i++){
sum+=(jc(n)/(jc(i)*jc(n-i)))*(int)Math.pow(i, k);
}
h=jc(n)/(jc(m)*jc(n-m));
System.out.println((sum*h)%999101);
}
public static int jc(int a){
int s=1;
for(int j=a;j>0;j--){
s*=j;
}
return s;
}
}运行结果:20
10
10
681684我的代码 2:改进import java.util.Scanner;
public class Result {
public static void main(String[] args) {
Scanner sca=new Scanner(System.in);
long n,m,k,sum=0,h;
n=sca.nextInt();
m=sca.nextInt();
k=sca.nextInt();
for(int i=1;i<=n;i++){
sum+=(jc(n)/(jc(i)*jc(n-i)))*(long)Math.pow(i, k);
}
h=jc(n)/(jc(m)*jc(n-m));
System.out.println((sum*h)%999101);
}
public static long jc(long a){
long s=1;
for(long j=a;j>0;j--){
s*=j;
}
return s;
}
}因为当数字很大时int已经不够放下数字,所以要设为长整形long。运行结果:20
10
10
54327虽然结果仍然是不对但是有所改进。
正确答案:
用到的知识 lucas定理 欧拉定理 或费马小定理 快速幂 数学组合公式推导
lucas定理 求C(n,m)%p
数论Lucas定理:是用来求 c(n,m) mod p的值,p是素数(从n取m组合,模上p)
描述为:
Lucas(n,m,p)=cm(n%p,m%p)* Lucas(n/p,m/p,p)
Lucas(x,0,p)=1;
而
cm(a,b)=a! * (b!*(a-b)!)^(p-2) mod p
也= (a!/(a-b)!) * (b!)^(p-2)) mod p
这里,其实就是直接求 (a!/(a-b)!) / (b!) mod p
由于 (a/b) mod p = a * b^(p-2) mod p
费马小定理 a^(p-1) mod p=1 (mod p)
import java.math.BigInteger;
import java.util.Scanner;
public class L_20END {
/***
* @author 林梵
*/
public static BigInteger lucas(BigInteger n,BigInteger m,BigInteger p){
if(m.equals(BigInteger.ZERO)) return BigInteger.ONE;
return BigInteger.valueOf(f(n.mod(p).longValue(),m.mod(p).longValue())).multiply(lucas(n.divide(p),m.divide(p),p)).mod(p);
}
public static long f(long n,long m){
if(m>n) return 1;
if(n==m|| m==0) return 1;
if(m>n-m) m=n-m;
long tmpi=1,tmpn=1,s1=1,s2=1,ans=1;
for (int i = 1; i<=m; i++) {
tmpi=i;
tmpn=n-i+1;
s1=s1*tmpi%999101;
s2=s2*tmpn%999101;
}
ans = s2*pow1(s1,999099)%999101;
return ans%999101;
}
public static long pow1(long x,long n) {
if(x==1) return 1;
if (n==0)
return 1;
else {
while ((n & 1)==0) {
n>>=1;
x=(x *x)%999101;
}
}
long result = x%999101;
n>>=1;
while (n!=0) {
x=(x *x)%999101;;
if ((n & 1)!=0)
result =result*x%999101;
n>>=1;
}
return result;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
BigInteger n = new BigInteger(sc.nextLine());
BigInteger m = new BigInteger(sc.nextLine());
int k = Integer.parseInt(sc.nextLine());
long start = System.currentTimeMillis();
BigInteger md = new BigInteger("999101");
long Cnm=lucas(n, m,md).longValue()%999101;
long sum = 0;
if(Cnm!=0){
int[][] a = new int[k][k];
int h = 1;
for (int i = 0; i < k; i++) {
for (int j = 0; j < k; j++) {
if (j >= h)
a[i][j] =0;
else {
if (j == 0 || j == h - 1)
a[i][j] = 1;
else {
a[i][j] = (a[i - 1][j - 1]*(h - j)+a[i - 1][j])%999101;
}
}
}
h++;
}
long m1 = 1,n1 =1;
long x=n.subtract(new BigInteger(k+"")).mod(md.subtract(BigInteger.ONE)).longValue();
long n3 = pow1(2,x);
for (int i = k - 1; i >= 0; i--) {
n1=n3*pow1(2,i)%999101;
m1 = m1*(n.subtract(new BigInteger((k - 1 - i) + "")).mod(md).longValue())%999101;
sum = (sum+m1*a[k - 1][i]*n1)%999101;
}
sum = sum*Cnm%999101;
}
System.out.println(sum);
long end = System.currentTimeMillis();
System.out.println(end - start);
}