light oj 1067 组合数取模

题目连接:http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=26784

题目:

Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu

Description:

Given n different objects, you want to take k of them. How many ways to can do it?

For example, say there are 4 items; you want to take 2 of them. So, you can do it 6 ways.

Take 1, 2

Take 1, 3

Take 1, 4

Take 2, 3

Take 2, 4

Take 3, 4

Input:

Input starts with an integer T (≤ 2000), denoting the number of test cases.

Each test case contains two integers n (1 ≤ n ≤ 106), k (0 ≤ k ≤ n).

Output:

For each case, output the case number and the desired value. Since the result can be very large, you have to print the result modulo 1000003.

题意:给你n和k,从n个different objects,选k个不同的,就是求组合数C(n,k)%1000003;

分析:

时间只有2秒,T组测试数据加上n的106达到了109递推肯定超时,那么考虑组合公式,C(n,k)=n!/(k!*(n-k)!);先打一个阶乘的表(当然要取模,只有106),然后就是这个除法取模的问题,当然是求逆元,(a/b)%mod=a*(b对mod 的逆元);求逆元可以用扩欧和费马小定理(可以啊、百度的);

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e6+5,mod=1000003;
typedef long long LL;
LL fact[maxn];
void f()
{
    fact[1]=fact[0]=1;
    for(int  i=2;i<maxn;i++)
        fact[i]=(LL)(i*fact[i-1])%mod;
}
LL niyuan(LL a,LL p)//就是个快速幂
{
    if(p==0)return 1;
    LL x=niyuan(a,p/2);
    LL ans=x*x%mod;
    if(p%2==1)ans=ans*a%mod;
    return ans;
}
LL c(int n,int k)
{
    LL fm=(fact[k]*fact[n-k])%mod;
    LL ans1=niyuan(fm,mod-2);//费马小定理,求一个幂就好;
    return (ans1*fact[n])%mod;
}
int main()
{
    int t,n,k,kase=0;
    f();//打表
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&k);
        if(k*2>n)
            k=n-k;//组合数对称性,减少计算;
        printf("Case %d: %lld\n",++kase,c(n,k));
    }
    return 0;
}

时间: 2024-08-09 23:43:09

light oj 1067 组合数取模的相关文章

LightOJ 1067 组合数取模

Description Given n different objects, you want to take k of them. How many ways to can do it? For example, say there are 4 items; you want to take 2 of them. So, you can do it 6 ways. Take 1, 2 Take 1, 3 Take 1, 4 Take 2, 3 Take 2, 4 Take 3, 4 Input

组合数取模终极版

以前讲述过很多组合数取模问题,详见:http://blog.csdn.net/acdreamers/article/details/8037918 今天,我们继续学习一些稍有难度的组合数取模问题,比如大组合数对合数取模,求大组合数的最后位数字等等. 首先来看组合数对合数取模问题 问题:求的值,其中和,并且是合数. 分析:先把素因子分解,然后转化为求,这里为素数,然后用CRT合并.所以现在重点来研究 如何求的值.这个问题AekdyCoin大神已经详细讲述了,如下链接     链接:http://h

排列组合+组合数取模 HDU 5894

1 // 排列组合+组合数取模 HDU 5894 2 // 题意:n个座位不同,m个人去坐(人是一样的),每个人之间至少相隔k个座位问方案数 3 // 思路: 4 // 定好m个人 相邻人之间k个座位 剩下就剩n-(m+1)*k个座位 5 // 剩下座位去插m个不同的盒子==就等价n个相同的球放m个不同的盒子 6 // 然后组合数出来了 7 // 乘n的话是枚举座位,除m是去掉枚举第一个座位的时候,剩下人相邻的座位相对不变的情况 8 9 #include <iostream> 10 #incl

大组合数取模之lucas定理模板,1&lt;=n&lt;=m&lt;=1e9,1&lt;p&lt;=1e6,p必须为素数

typedef long long ll; /********************************** 大组合数取模之lucas定理模板,1<=n<=m<=1e9,1<p<=1e6,p必须为素数 输入:C(n,m)%p 调用lucas(n,m,p) 复杂度:min(m,p)*log(m) ***********************************/ //ax + by = gcd(a,b) //传入固定值a,b.放回 d=gcd(a,b), x , y

组合数取模Lucas定理及快速幂取模

组合数取模就是求的值,根据,和的取值范围不同,采取的方法也不一样. 下面,我们来看常见的两种取值情况(m.n在64位整数型范围内) (1)  , 此时较简单,在O(n2)可承受的情况下组合数的计算可以直接用杨辉三角递推,边做加法边取模. (2) ,   ,并且是素数 本文针对该取值范围较大又不太大的情况(2)进行讨论. 这个问题可以使用Lucas定理,定理描述: 其中 这样将组合数的求解分解为小问题的乘积,下面考虑计算C(ni, mi) %p. 已知C(n, m) mod p = n!/(m!(

hdu 3037 Saving Beans 组合数取模模板题。。

Saving Beans Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2707    Accepted Submission(s): 1014 Problem Description Although winter is far away, squirrels have to work day and night to save b

toj 4111 组合数取模 暴力分解

题目大意:组合数取模,n和m并不算大,p比较大且是合数. 思路:暴力分解+快速幂 注:暴力也是有区别的,分解质因数时可以用以下work函数,写的非常巧妙,摘录自互联网. 1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 5 typedef long long ll; 6 const ll mod = 1ll << 32; 7 const int N = 1000001; 8 const

[BZOJ 3129] [Sdoi2013] 方程 【容斥+组合数取模+中国剩余定理】

题目链接:BZOJ - 3129 题目分析 使用隔板法的思想,如果没有任何限制条件,那么方案数就是 C(m - 1, n - 1). 如果有一个限制条件是 xi >= Ai ,那么我们就可以将 m 减去 Ai - 1 ,相当于将这一部分固定分给 xi,就转化为无限制的情况了. 如果有一些限制条件是 xi <= Ai 呢?直接来求就不行了,但是注意到这样的限制不超过 8 个,我们可以使用容斥原理来求. 考虑容斥:考虑哪些限制条件被违反了,也就是说,有哪些限制为 xi <= Ai 却是 xi

大组合数取模

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1119 考虑从(1,1)->(n,m)必定会向下走n-1步,向右走m-1步,那么总的走法是C(n-1+m-1,m-1). 关于组合数取模:大神博客:http://blog.csdn.net/acdreamers/article/details/8037918 1 #include <iostream> 2 #include <string.h> 3 #