1. 程式人生 > >(組合數問題)牛客網Wannafly挑戰賽17 B題 求值2

(組合數問題)牛客網Wannafly挑戰賽17 B題 求值2

連結:https://www.nowcoder.com/acm/contest/114/B
來源:牛客網
 

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 262144K,其他語言524288K
64bit IO Format: %lld

題目描述

Ans = 0; 
For(inti = 1; i <= n; i++) 
    For(int v = 0; v <= n; v++) 
        Ans = (Ans + C(i, v) * C(i, v)) % 998244353;

C(i,v)為組合數第i行第v列的數。
給你上面的程式碼中的n,請你輸出Ans的值。

輸入描述:

輸入一個整數n

輸出描述:

輸出Ans的值。

示例1

輸入

複製

3

輸出

複製

28

備註:

n<=106

首先C(i,v)組合數中,v必定小於i,所以v的範圍是[0,i]。對於每個i我們需要計算C(i,0)+C(i,1)+........C(i,i)。這個式子有個公式等於C(2i,i)。那麼對於每個i我們需要將這個組合數相加,我們需要計算C(2,1)+C(4,2)+.....C(2n,n)   

我們根據公式推導,發現C(2i,i)=C(2(i-1),i-1)*(4i-2)/i%mod,所以我們只需要用一個迴圈就能表達這個式子。

但這個時候我們發現,除以i之後再取模和取模之後再除i結果是不一樣的。這就涉及到了逆元的問題,a/b%(mod)=a*b^(-1)%mod     其中 b^(-1)就是b的逆元。

根據費馬小定理 a^p=a mod p    (前提a是整數,p是素數)   如果a不是p的整數倍 a^(p-1)=1 mod p  

我們令 c=b^(-1)   c*b=1 mod p=b^(p-1)  ,所以 c 可以寫成 b^(p-2) mod p。那麼推導式為:

C(2i,i)=C(2(i-1),i-1)*(4i-2)*i^(mod-2)%mod 這樣計算式中都是乘法就不存在除法的問題以下為原始碼。

#include<stdio.h>
#include<string.h>

#define mod 998244353

int qpow(long long b,int m){
	long long sum=1;
	
	while(m){
		if(m%2) sum=sum*b%mod;
		m=m/2;
		b=b*b%mod;
	}
	return sum;
}

int main(){
	int i,n;
	long long b,a,m2;
	
	while(scanf("%d",&n)!=EOF){
		b=0;
		a=1;
		for(i=1;i<=n;i++){
			a=a*(4*i-2)%mod;
			m2=qpow(i,mod-2);
			a=a*m2%mod;
			b=(b+a)%mod;	
		}
		printf("%lld\n",b);
	}	
	
	return 0;
}