题目链接:http://acm.swust.edu.cn/problem/0247/

Time limit(ms): 1000        Memory limit(kb): 65535
 
Description
在很久很久以前,有个臭美国王。一天,他得到了一件新衣,于是决定巡城看看老百姓的反应(囧)。于是他命令可怜的宰相数一下他有多少种巡城方案。 
城市是一个N*M的矩形,(N+1)*(M+1)条街把城市分成了N*M块。国王从左下角出发,每次只能向右或向上走,右上角是终点。 
请你帮帮可怜的宰相。

 
Input
每组测试数据有3个值 n m p(0< n <=1000000000,0 < m <=1000000000,p为质数且p<400). 
 
Output
多组测试数据 0 0 0结束。
输出方案数 因为数据太大 请 mod p

 
Sample Input
2 3 97
20 40 37
0 0 0
Sample Output
10
32
 
Hint
2009暑期ACM集训组队赛《一》 -- 剑问苍生
 
解题思路:从左下角到右上角的方案数,那么(假设方阵大小n*m)
     (1)向上必须移动n格,向右必然移动m格
     (2)只需要以向上或向右移动为基准求C(n+m) n 或者C(n+m) m的组合数即可,好好想想为什么吧~~~~
        可以有一个优化组合数上面的去n,m中的较小值(组合数性质)
     (3)发现n,m<=1000000000那么在求组合数的时候肯定会直接爆掉,那怕是在求的过程中不断MOD 数p,
       那么我们以p的上限值为界求组合数,运用Lucas定理求解
 
Lucas定理:(详情可以戳戳这里:http://www.cnblogs.com/zyxStar/p/4588362.html)

      Lucas定理用来求C(a,b)mod p的值,其中p为素数。
      数学表达式为:
      Lucas(a,b,q)=C(a%q,b%q)*Lucas(a/p,b/p,p);
      Lucas(a,0,q)=0;

      模运算与基本四则运算有些相似,但是除法例外。其规则如下:
      (a + b) % p = (a % p + b % p) % p (1)
      (a - b) % p = (a % p - b % p) % p (2)
      (a * b) % p = (a % p * b % p) % p (3)
      a ^ b % p = ((a % p)^b) % p (4)

代码如下:

 #include <iostream>
#include <cstring>
#include <algorithm>
#define maxn 405
using namespace std;
long long dp[maxn][maxn], n, m, p;
long long Lucas(long long n, long long m, long long p){
//Lucas定理
if (n <= p && m <= p)
return dp[n][m];
else
return (Lucas(n / p, m / p, p)*dp[n%p][m%p]) % p;
} //杨辉三角求组合数
void init(){
int i, left, right;
for (i = ; i <= p; i++){
dp[i][] = dp[i][i] = ;
left = , right = i - ;
while (left <= right){
dp[i][left] = (dp[i - ][left - ] + dp[i - ][left]) % p;
dp[i][right--] = dp[i][left++];//组合数性质dp[i][j]=dp[i][i-j];
}
}
}
int main(){
while (cin >> n >> m >> p && n && m && p){
memset(dp, , sizeof(dp));
init();
cout << Lucas(n + m, min(n, m), p) << endl;
}
return ;
}

乱搞的Java代码如下:

 import java.math.*;
import java.io.*;
import java.util.*;
public class Main{
static int DP[][] = new int[401][401];
static int p;
public static void main(String[] args)
{
Scanner cin = new Scanner(System.in);
int a, b;
while (cin.hasNext()){
a = cin.nextInt();
b = cin.nextInt();
p = cin.nextInt();
if (a == 0)
break;
initDp();
System.out.println(sloveRe(a + b, b > a ? a : b));
}
}
private static void initDp(){
int i, j;
for (i = 0; i <= p; i++){
DP[i][0] = 1;
}
for (i = 1; i <= p; i++){
for (j = 1; j <= p; j++){
DP[i][j] = (DP[i - 1][j] + DP[i - 1][j - 1]) % p;
}
}
}
private static int sloveRe(int n, int m){
if (n <= p&&m <= p)
return DP[n][m];
else
return (sloveRe(n / p, m / p)*DP[n%p][m%p]) % p;
}
}

[Swust OJ 247]--皇帝的新衣(组合数+Lucas定理)的更多相关文章

  1. uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT)

    uoj86 mx的组合数 (lucas定理+数位dp+原根与指标+NTT) uoj 题目描述自己看去吧( 题解时间 首先看到 $ p $ 这么小还是质数,第一时间想到 $ lucas $ 定理. 注意 ...

  2. 【BZOJ-4591】超能粒子炮·改 数论 + 组合数 + Lucas定理

    4591: [Shoi2015]超能粒子炮·改 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 95  Solved: 33[Submit][Statu ...

  3. luogu4345 [SHOI2015]超能粒子炮·改(组合数/Lucas定理)

    link 输入\(n,k\),求\(\sum_{i=0}^k{n\choose i}\)对2333取模,10万组询问,n,k<=1e18 注意到一个2333这个数字很小并且还是质数这一良好性质, ...

  4. 【(好题)组合数+Lucas定理+公式递推(lowbit+滚动数组)+打表找规律】2017多校训练七 HDU 6129 Just do it

    http://acm.hdu.edu.cn/showproblem.php?pid=6129 [题意] 对于一个长度为n的序列a,我们可以计算b[i]=a1^a2^......^ai,这样得到序列b ...

  5. 组合数(Lucas定理) + 快速幂 --- HDU 5226 Tom and matrix

    Tom and matrix Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=5226 Mean: 题意很简单,略. analy ...

  6. 【组合数+Lucas定理模板】HDU 3037 Saving

    acm.hdu.edu.cn/showproblem.php?pid=3037 [题意] m个松果,n棵树 求把最多m个松果分配到最多n棵树的方案数 方案数有可能很大,模素数p 1 <= n, ...

  7. CodeForces-451E:Devu and Flowers (母函数+组合数+Lucas定理)

    Devu wants to decorate his garden with flowers. He has purchased n boxes, where the i-th box contain ...

  8. HDU3037Saving Beans(组合数+lucas定理)

    Problem Description Although winter is far away, squirrels have to work day and night to save beans. ...

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

    组合数取模就是求的值,根据,和的取值范围不同,采取的方法也不一样. 下面,我们来看常见的两种取值情况(m.n在64位整数型范围内) (1)  , 此时较简单,在O(n2)可承受的情况下组合数的计算可以 ...

随机推荐

  1. jbpmAPI-8

    8.1. Process Instance State jBPM允许某些信息的持久性存储.本章描述了这些不同类型的持久性,以及如何配置它们.存储的信息的一个例子是运行时状态的过程.存储过程运行时状态是 ...

  2. ipc$爆破密码

    FOR /L %%i IN (1,1,99) DO net use \\192.168.1.1\ipc$ /user:test %%i && echo %%i>1.txt

  3. IPv6地址的ping、telnet等操作

    最近在研究https协议是如何传输数据的,用wireshark抓包分析,发现客户机和google网站在传输数据时使用了IPv6地址,于是相对ipv6地址测试下基本的功能. ping功能,直接使用pin ...

  4. WIZnet即将推出高性能网络芯片W5500

    WIZnet将于9月份推出高性能网络芯片W5500,这是继W5100.W5200和W5300之后一款全新的全硬件TCP/IP协议栈网络芯片,这款芯片具有更低功耗与工作温度,及改良工艺,是嵌入式以太网的 ...

  5. HDU 3307 Description has only two Sentences

    数学实在是差到不行了…… #include <cstdio> #include <cstring> #include <algorithm> #include &l ...

  6. [置顶] 【J2SE 】1136 容器之旅

    开篇引言 本篇文章我将要详细的介绍一下什么是容器?以及什么是1136?来系统全面的了解容器,以及容器的应用,下面就进入我们的容器之旅吧! 1.什么是容器? 用来存储和组织其他对象的对象.我们也可以这样 ...

  7. 4种Java引用浅解

    近期研究Java Cache实现,发现使用到了软引用(SoftReference),不太理解,查阅了JDK文档.代码以及几篇文章.做个小结,如有错误,欢迎指正. 之所以想学习一下Java的几种引用类型 ...

  8. JNI(2)

    JNI(2) 访问字段和方法 JNI允许本地代码访问java 对象的字段和方法. 调用需要两个步骤: 例如调用cls类的f方法, 1. 获取方法ID jmethodID mid = env->G ...

  9. javascript技术难点之this、new、apply和call详解

    讲解this指针的原理是个很复杂的问题,如果我们从javascript里this的实现机制来说明this,很多朋友可能会越来越糊涂,因此本篇打算换一个思路从应用的角度来讲解this指针,从这个角度理解 ...

  10. 使用Groovy进行依赖注入

    为什么选择Groovy? 传统的依赖注入是XML,对我而言,可读性太差,太不美观,强烈地想换一个方式进行依赖注入,Groovy作为XML的替代方案,在Spring4之后被引入,是基于JVM的一门方言, ...