HDU3944 DP? (LUCAS定理+階乘預處理)
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
題目分析:要求計算最小的和,
當 k < n/2 時需要將C(N,K) 化成 C(N,N-K);
原式 C(N,K)+C(N-1,K-1)+...+C(N-K,0)+K;
由 C(N-1,K)+C(N-1,K-1)=C(N,K) 原式可化為C(N+1,K)+K;
然後經過Lucas定理+對階乘的預處理即可得出結果;
程式碼如下:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 10005;
bool prime[N];
int p[N],f[N][N],inv[N][N],cnt,pth[N];
void isprime(){
cnt=0;
memset(prime,1,sizeof(prime));
for(int i=2;i<N;i++){
if(prime[i]){
p[++cnt]=i;
pth[i]=cnt;
for(int j=i+i;j<N;j+=i)
prime[j]=0;
}
}
}
int quick_mod(int a,int b,int m){
int ans=1;
a%=m;
while(b){
if(b&1){
ans=ans*a%m;
b--;
}
b>>=1;
a=a*a%m;
}
return ans;
}
void init(){//預處理階乘與逆元
int i,j;
for(int i=1;i<=cnt;i++){
f[i][0]=inv[i][0]=1;
for(int j=1;j<p[i];j++){
f[i][j]=(f[i][j-1]*j)%p[i];
inv[i][j]=quick_mod(f[i][j],p[i]-2,p[i]);
}
}
}
int com(int n,int m,int P){
if(m>n) return 0;
if(m==n) return 1;
int t=pth[P];
return f[t][n]*(inv[t][n-m]*inv[t][m]%P)%P;
}
int lucas(int n,int m,int P){
if(m==0) return 1;
return com(n%P,m%P,P)*lucas(n/P,m/P,P)%P;
}
int main()
{
int cas=1,n,m,P;
isprime();
init();
while(cin>>n>>m>>P){
if(m<=n/2) m=n-m;
n++;
printf("Case #%d: %d\n",cas++,(m%P+lucas(n,m+1,P))%P);
}
return 0;
}
相關文章
- 盧卡斯定理(Lucas定理)
- [Lucas定理] 集合計數
- HDU4675 GCD of Sequence(預處理階乘逆元+推公式)GC公式
- HDU 4455 Substrings(預處理+dp)
- HDU 4349 Xiao Ming's Hope (Lucas定理的應用)
- 費馬小定理-期望dp
- 【演算法學習筆記】組合數與 Lucas 定理演算法筆記
- 列舉子集+預處理最佳化dp+貪心視角轉化成可做dp
- 【DP】乘積最大子陣列陣列
- 影像預處理
- 預處理指令
- 預處理命令
- 資料預處理
- 影像預處理方法
- 計算階乘
- ACM 階乘之和ACM
- DP進階合集
- 資料預處理 demo
- 預設型DP
- 預設型 DP
- c++進階(一)C語言條件編譯及編譯預處理階段C++C語言編譯
- NOIP2000乘積最大[序列DP]
- hdu5435 數位dp(大數的處理)
- 【scikit-learn基礎】--『預處理』之 缺失值處理
- nlp 中文資料預處理
- 機器學習一:資料預處理機器學習
- 文字檢測預處理地址
- 程式環境和預處理
- 影像預處理包括哪些東東?
- split用法與影像預處理
- 特徵工程之特徵預處理特徵工程
- 資料預處理規則
- 資料預處理的形式
- 預處理技術文獻
- 第五篇:資料預處理(二) - 異常值處理
- 第四篇:資料預處理(一) - 缺失值處理
- SPM12之fMRI批次預處理——NII檔案處理
- Java進階02 異常處理Java