HDU3944-DP?(帕斯卡公式+Lucas定理)

DP?

Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 128000/128000 K (Java/Others)

Total Submission(s): 1930    Accepted Submission(s): 640

Problem Description

Figure 1 shows the Yang Hui Triangle. We number the row from top to bottom 0,1,2,…and the column from left to right 0,1,2,….If using C(n,k) represents the number of row n, column k. The Yang Hui Triangle has a regular pattern as follows.

C(n,0)=C(n,n)=1 (n ≥ 0)

C(n,k)=C(n-1,k-1)+C(n-1,k) (0<k<n)

Write a program that calculates the minimum sum of numbers passed on a route that starts at the top and ends at row n, column k. Each step can go either straight down or diagonally down to the right like figure 2.

As the answer may be very large, you only need to output the answer mod p which is a prime.

Input

Input to the problem will consists of series of up to 100000 data sets. For each data there is a line contains three integers n, k(0<=k<=n<10^9) p(p<10^4 and p is a prime) . Input is terminated by end-of-file.

Output

For every test case, you should output "Case #C: " first, where C indicates the case number and starts at 1.Then output the minimum sum mod p.

Sample Input

1 1 2
4 2 7

Sample Output

Case #1: 0
Case #2: 5

Author

[email protected]

题意:告诉你在一个在杨辉三角中的点,问你从走到0,0点做到该店经过的点最少的权值和,而且只能走向下和,斜向下两个方向。

思路:容易看出,根据已知的那个点(n,m) 如果 n > 2*m 那么从已知点出发,可以一直往斜的方向走,直到边界,那么 权值和就为 C(n,m)+C(n-1,m-1)....... 由帕斯卡公式可得该式等于 C(n+1,m)+(n-m)  如果n <= 2*m,那么就是一直往上走,权值和就为C(n,m)+C(n-1,m)+C(n-2,m)..... 等于C(n+1,m+1)+m

得到公式之后因为n,m很大,所以需要用Lucas定理化简,而且样例有1e5组,因此要先将素数的一些组合数打好表。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
int n,m,p;
const int maxn = 10000+10;
bool isPrime[maxn];
int CC[maxn][maxn];
int AA[maxn][maxn];
void gcd(int a,int b,int &d,int &x,int &y){
    if(!b){
        d = a;
        x = 1;
        y = 0;
    }else{
        gcd(b,a%b,d,y,x);
        y -= x*(a/b);
    }

}
inline int inv(int a,int p){
    int d,x,y;
    gcd(a,p,d,x,y);
    return (d==1)?(x+p)%p:-1;
}
inline int C(int nn,int mm){
    int ans;
    if(nn<mm) return 0;
    if(nn==mm||mm==0) return 1;
    if(mm==1||mm==nn-1) return nn;
    ans = (((AA[p][nn]*CC[p][mm])%p)*CC[p][nn-mm])%p;
    return ans;
}
int Lucas(int nn,int mm){
    if(mm==0) return 1;
    int k = C(nn%p,mm%p);
    return (k*Lucas(nn/p,mm/p))%p;
}
void init(){
    memset(isPrime,1,sizeof isPrime);
    int id = 0;
    for(int i = 2; i < maxn; i++){
        if(isPrime[i]){
            CC[i][2] = inv(2,i);
            for(int j = 3; j < i; j++){
                CC[i][j] = (CC[i][j-1]*inv(j,i))%i;
            }
            for(int j = i*i; j < maxn; j+=i){
                isPrime[j] = 0;
            }
            AA[i][1] = 1;
            for(int j = 2; j < i; j++){
                AA[i][j] = (AA[i][j-1]*j)%i;
            }
        }
    }
}
int main(){
    int T = 1;
    init();
    while(scanf("%d%d%d",&n,&m,&p) != EOF){
        if(2*m < n)
            printf("Case #%d: %d\n",T++,(Lucas(n+1,m)+n-m)%p);
        else
            printf("Case #%d: %d\n",T++,(Lucas(n+1,m+1)+m)%p);
    }
    return 0;
}

HDU3944-DP?(帕斯卡公式+Lucas定理)

时间: 2024-10-13 22:26:14

HDU3944-DP?(帕斯卡公式+Lucas定理)的相关文章

BZOJ4737 组合数问题 【Lucas定理 + 数位dp】

题目 组合数C(n,m)表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3)三个物品中选择两个物品可以有( 1,2),(1,3),(2,3)这三种选择方法.根据组合数的定义,我们可以给出计算组合数C(n,m)的一般公式: C(n,m)=n!/m!*(n?m)! 其中n!=1×2×?×n.(额外的,当n=0时,n!=1) 小葱想知道如果给定n,m和k,对于所有的0≤i≤n,0≤j≤min(i,m)有多少对(i,j)满足C(i,j)是k的倍数. 输入格式 第一行有两个整数t,k,其中

【bzoj2111】[ZJOI2010]Perm 排列计数 dp+Lucas定理

题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Mogic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Mogic的,答案可能很大,只能输出模P以后的值 输入 输入文件的第一行包含两个整数 n和p,含义如上所述. 输出 输出文件中仅包含一个整数,表示计算1,2,?, n的排列中, Mogic排列的个数模 p的值. 样例输入 20 23 样例输出 16 题解 dp+Lucas定理 题目显然小根堆,考虑怎么求以一个节点为根的方案数.根肯定

【bzoj3782】上学路线 dp+容斥原理+Lucas定理+中国剩余定理

题目描述 小C所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M).小C家住在西南角,学校在东北角.现在有T个路口进行施工,小C不能通过这些路口.小C喜欢走最短的路径到达目的地,因此他每天上学时都只会向东或北行走:而小C又喜欢走不同的路径,因此他问你按照他走最短路径的规则,他可以选择的不同的上学路线有多少条.由于答案可能很大,所以小C只需要让你求出路径数mod P的值. 输入 第一行,四个整数N.M.T.P. 接下来的T行,每行两个整数,表示施工的路口的坐标. 输出 一

bzoj 1902: Zju2116 Christopher lucas定理 &amp;&amp; 数位DP

1902: Zju2116 Christopher Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 172  Solved: 67[Submit][Status][Discuss] Description 给定n个元素,要从中间选择m个元素有多少种方案呢?答案很简单,就是C(n,m).如果一个整数m(0≤m≤n),C(n,m)是某一个质数p的倍数,那么这个m就是讨厌的数字,现在给定了p和n,求有多少个讨厌的数字. Input 第一行是一个正整数n,(1

Lucas定理 、斯特灵公式

斯特灵公式是一条用来取n阶乘的近似值的数学公式. 公式为: 用该公式我们可以用来估算n阶乘的值:估算n阶乘的在任意进制下的位数. 如何计算在R进制下的位数:我们可以结合对数来计算,比如十进制就是lg(n!)+1,二进制则是log2(n!)+1. Lucas(卢卡斯)定理 公式为:(p为质数) 当然,当n较小时,我们可以用组合数里面的定理来递推求解. 然而当n较大时,显然时间花费很大.而Lucas定理恰好是解决大组合数取模的优解. 在这里由于知识有限,不能完全看懂Lucas定理证明的全部过程.所以

[CTSC2017][bzoj4903] 吉夫特 [状压dp+Lucas定理]

题面 传送门 思路 一句话题意: 给出一个长度为 n 的序列,求所有长度大于等于2的子序列个数,满足:对于子序列中任意两个相邻的数 a和 b (b 在 a 前面),\(C_a^b mod 2=1\),答案对1e9+7取模 显然膜2余1是个非常特殊的性质,应当好好加以利用 和组合数取模有关的东西,有Lucas定理,因此我们来试着推一推 \(C_n^m%2=C_{n%2}^{m%2}\ast C_{n/2}^{m/2}\) 这个玩意的意义,显然就是把n和m转成二进制,那么只要没有某一位上n是0m是1

hdu 3944 DP? (Lucas 定理)

仔细观察杨辉三角后可以发现从最高点到第n行第k个数的最短路为c(n+1,k); 根据Lucas定理可以求出,一般来说要求答案模去一个质数p且p的范围不大于10^5则可用Lucas. Lucas(n,m,p)=cm(n%p,m%p)* Lucas(n/p,m/p,p) Lucas(x,0,p)=1; 另外注意当k>n/2时,必须令k=n-k. #include <iostream> #include <cstdio> #include <cstring> #incl

bzoj 2111 [ZJOI2010]Perm 排列计数(DP+lucas定理)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2111 [题意] 给定n,问1..n的排列中有多少个可以构成小根堆. [思路] 设f[i]为以i为根的方案数,设l为左子树大小r为右子树大小,则有: f[i]=C(i-1,l)*f[l]*f[r] 因为是个堆,所以子树大小都是确定的,可以直接递推得到. 其中C(n,m) nm比较大,可以用lucas定理求. 模型建立的重要性可知一二... [代码] 1 #include<cstdio>

HDU 3037 Saving Beans 多重集合的结合 lucas定理

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3037 题目描述: 要求求x1 + x2 + x3 + ...... + xn <= m 非负整数解的个数, 结果对P取模, 输入的变量是n, m, p, P一定是素数 解题思路: x1 + ... + xn = m 非负整数解的个数是C(n+m-1, n) , 所以答案就是 C(n+0-1, 0) + C(n+1-1, 1) + ...... C(n+m-1, n) 对P取模, 由于组合数公式C(