hdu5968(組合數取模Lucas定理)
阿新 • • 發佈:2019-01-27
瞬間移動
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1460 Accepted Submission(s): 703
Problem Description 有一個無限大的矩形,初始時你在左上角(即第一行第一列),每次你都可以選擇一個右下方格子,並瞬移過去(如從下圖中的紅色格子能直接瞬移到藍色格子),求到第n行第m列的格子有幾種方案,答案對1000000007取模。
Input 多組測試資料。
兩個整數n,m(2≤n,m≤100000)
Output 一個整數表示答案
Sample Input 4 5
Sample Output 10 思路:這個矩形形成了一個楊輝三角,座標(n,m)對應楊輝三角中的座標(n+m-3,m-1),又因為楊輝三角中第n行的m個數可表示為 C(n-1,m-1),所以結果就為C(n+m-4,m-2),再使用Lucas定理求出組合數取模即可。
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> using namespace std; typedef long long LL; #define MOD 1000000007 LL n,m; LL p=MOD; LL quick_mod(LL a, LL b) { LL ans = 1; a %= p; while(b) { if(b & 1) { ans = ans * a % p; b--; } b >>= 1; a = a * a % p; } return ans; } LL C(LL n, LL m) { if(m > n) return 0; LL ans = 1; for(int i=1; i<=m; i++) { LL a = (n + i - m) % p; LL b = i % p; ans = ans * (a * quick_mod(b, p-2) % p) % p; } return ans; } LL Lucas(LL n, LL m) { if(m == 0) return 1; return C(n % p, m % p) * Lucas(n / p, m / p) % p; } int main() { while(~scanf("%lld%lld",&n,&m)) { printf("%lld\n",Lucas(n+m-4,m-2)); } }