[CSP-Sシミュレーション試験]:順列(または数学的法則を見つけます。)

タイトル説明

$ 7 $ 10 ^ 9 +モジュロのデータの$のTの$セット、N- $ $所与それぞれ、以下の式の値を要求します。

$$ C_N ^ 0 \回C_N ^ 0 + C_N ^ 1 \回C_N ^ 1 + C_N ^ 2 \回C_N ^ 2 + ... + C_N ^ n回C_N ^ nと\ $$


入力形式

最初の行の整数の$ T $は、データセットの数を表します。
その後、$ T $行は、それぞれ、示したタイトルの意味としてN- $の$整数を含みます。


出力フォーマット

$ Tの$出力ライン、応答モード後に採取した$ 10 $ ^ 7 + 9を表す整数をそれぞれ含みます。


サンプル

サンプル入力:

2
1
2

出力例:

2
6


データ範囲とヒント

$ 30 \%の$のデータについて、$ T \ 500をleqslant、n個 \ 10,000 $をleqslant。
$ \ 100%の$のデータについて、$ T \ 100,000、n個leqslantの\ leqslant 1,000,000 $を。


問題の解決策

私はあなたにすべての幸せなナショナルデー、幸せなトレーニングをしたいです!

答えはで見つけることができる法律を見つけるためにテーブルをヒットすると、実際に$ C_ {2N} ^ n個の$であるので、私たちは今、なぜある最後にこのことについて話しています。

まず、物語の観点:

家の前2本の木があり、一つはナツメは、ナツメは別のものです。 - 魯迅

私の家の前を2つのナツメがあり、$ nの$粒子のナツメナツメの木、他方はまた、$ N $の粒子はナツメの木を持っているナツメがあります。 - $ HEOI- $ドードー

Maのは、私は、どのように多くのプログラムの数がありますされているこの2ナツメで$ n $というナツメの木を選んでみましょうか?

要約私たちは、私が最初にナツメの木の上に粒子を$ $と仮定し、その後、別のツリーが$ $ Ni粒子の日付を選択するために、プログラム番号は次のとおりです。$ C_Nは^私はC_N ^ {NI} $、その後、プログラム全体の時間を\します$ \和の\ limits_ {I = 0} ^ N C_N ^ iは時間C_N ^ {NI} $を\の数です。

ツリーは同じであるが、日が同じである、は、プログラムの数も書くことができる:$ C_ {2N} ^ n個の$。

それは^私は倍C_N ^ {NI} $を\ $ C_ {2N} ^ n個= \和の\ limits_ {I = 0} ^ nはC_Nです。

^ I = C_N {NI} $ $ C_Nを知っている我々はまた、次の式になる:$ C_ {2N} ^ N = \和の\ limits_ {I = 0} ^ N {(C_N ^ I)} ^ 2 $。

那么$ C_N ^ 0 \回C_N ^ 0 + C_N ^ 1 \回C_N ^ 1 + C_N ^ 2 \回C_N ^ 2 + ... + C_N ^ N \回C_N ^ N = C_ {2N} ^ n個の$。

私は、子どもたちがまあ〜について理解、話を終えました

時間計算:$ \シータ(T \時間\ LOG_ {MOD} N)$。

期待はスコア:$ $ 100ポイントを。

実際のスコア:$ $ 100ポイント。


コードの時間

#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int n;
long long jc[2000001],inv[2000001];
long long qpow(long long x,long long y)
{
	long long res=1;
	while(y)
	{
		if(y%2)res=res*x%mod;
		y>>=1;
		x=x*x%mod;
	}
	return res;
}
void pre_work()
{
	jc[0]=1;
	for(long long i=1;i<=2000000;i++)
		jc[i]=jc[i-1]*i%mod;
	inv[2000000]=qpow(jc[2000000],1000000005)%mod;
	for(long long i=2000000;i>0;i--)
		inv[i-1]=inv[i]*i%mod;
}
long long get_C(int x,int y){return jc[x]*inv[y]%mod*inv[x-y]%mod;}
int lucas(int x,int y)
{
	if(!y)return 1;
	return get_C(x%mod,y%mod)*lucas(x/mod,y/mod)%mod;
}
int main()
{
	pre_work();
	int T;scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		printf("%d\n",lucas(n<<1,n));
	}
	return 0;
}

rp++

おすすめ

転載: www.cnblogs.com/wzc521/p/11616116.html