hdu 3944 DP? lucas定理
2015-09-01 18:42
267 查看
DP?
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 128000/128000 K (Java/Others)Total Submission(s): 2460 Accepted Submission(s): 769
Problem Description
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/08/68ba60d4a793fa9a0a3fbdbcccd96a3f.jpg)
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
phyxnj@UESTC
Source
2011 Multi-University Training Contest 11 -
Host by UESTC
预处理出所有质数p,n!%p以及n!对于p的逆元,
然后 http://www.tuicool.com/articles/E3yaIn看这个博客吧。
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> using namespace std; #define maxn 10001 int check[maxn]; int jie[maxn][maxn]; int ni[maxn][maxn]; int cal(int n,int t,int p){ int ans = 1; while(t){ if(t&1) ans = ans*n%p; n = n*n%p; t/=2; } return ans; } void init(){ memset(check,0,sizeof(check)); for(int i = 2;i < maxn; i++){ if(!check[i]){ for(int j=i+i;j < maxn; j+=i) check[j] = 1; jie[i][0] = ni[i][0] = 1; for(int j = 1;j < i ;j++){ jie[i][j] = jie[i][j-1]*j%i; ni[i][j] = cal(jie[i][j],i-2,i); } } } } int Lucas(int n,int m,int p){ if(m == 0) return 1; int ans = 1; int a = n%p,b=m%p; if(b > a) return 0; ans = jie[p][a]*ni[p][a-b]%p*ni[p][b]%p; return Lucas(n/p,m/p,p)*ans%p; } int main(){ init(); int tt=1,n,m,p,ans; while(scanf("%d%d%d",&n,&m,&p)!=EOF){ if(n/2>=m) ans = (Lucas(n+1,m,p)+n-m)%p; else ans = (Lucas(n+1,m+1,p)+m)%p; printf("Case #%d: %d\n",tt++,ans); } return 0; }
相关文章推荐
- 【AngularJS】—— 12 独立作用域
- JQuery中的DOM操作
- nio文件通道
- leetcode 2: Add Two Numbers
- JAVA之编码/解码 -- 各种环境下可能会发生的乱码问题及解决方案
- Pdf格式文件怎么修改
- poj 1286 Necklace of Beads (polya(旋转+翻转)+模板)
- 周记——20150831
- 海盗分宝石
- 人月神话读后感
- EAIntroView–高度可定制的iOS应用欢迎页通用解决方案
- ORACLE索引失效原因归纳[转]
- 论char数组在c++和java中的不同
- 第二届CCF软件能力认证
- iOS js oc相互调用(JavaScriptCore)(二)
- Python - Headless Selenium WebDriver Tests using PyVirtualDisplay
- Windows下使用MongoDb的经验
- HDU 1106 排序
- 100个高质量Java开发者博客
- unity3d 2d 射线检测