hdu5673-Robot
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=5673
好久没打BC,当时这场过了3题,hack了一个,马马虎虎吧,因为前三个题确实不难。
这个是那场的第四个题,其实难度不大。结果是ΣC(n,2i)*catalan[i],C(n,2i)好理解。
卡特兰数吗。。。。其实也不太负责,因为卡特兰数经常用在括号匹配啊啥的情况。。。参见这个吧。。
http://blog.csdn.net/hongchangfirst/article/details/8766529
http://blog.chinaunix.net/uid-26456800-id-3462158.html
当然,这题数据量比较大,建议用递推公式,涉及到求逆元,费马小定理+快速幂可以。
几个递推:Catalan[i] = ((4*i-2)/(i+1))*Catalan[i-1] , C(n, i) = ((n-i+1)/i)*C(n, i-1)。
至于网上人用的这个线性的。。。。inv[i]=(mod-mod/i)*inv[mod%i]%mod;。。。还没研究明白。。
代码:
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 const int maxn = 1000000 + 100; 5 typedef long long int64; 6 const int64 mod = 1000000000 + 7; 7 8 int64 inv[maxn]; 9 int64 catalan[maxn], c[maxn]; 10 11 int64 fpow( int x, int64 p ){ 12 //cout << x << " " << p << endl; 13 int64 ans = 1, sum = x; 14 while(p){ 15 if(p&1) 16 ans = (ans * sum)%mod; 17 sum = (sum * sum)%mod; 18 p >>= 1; 19 } 20 21 return ans; 22 } 23 24 void Init(void){ 25 inv[1] = 1; 26 for( int i = 2; i < maxn; ++i ){ 27 //inv[i]=(mod-mod/i)*inv[mod%i]%mod; 28 inv[i] = fpow(i, mod-2); 29 } 30 31 catalan[0] = catalan[1] = 1; 32 for( int i = 2; i < maxn; ++i ){ 33 int a = 4*i-2, b = i+1; 34 catalan[i] = catalan[i-1]*a%mod*inv[b]%mod; 35 } 36 //cout << catalan[3] << " " << catalan[4] << " " << catalan[5] << endl; 37 } 38 39 void solve(int n){ 40 int64 ans = 1; 41 42 c[0] = 1; 43 for( int i = 1; i <= n; ++i ){ 44 c[i] = (n-i+1)*c[i-1]%mod*inv[i]%mod; 45 } 46 47 for( int i = 1; i*2 <= n; ++i ){ 48 ans = (ans + c[2*i]*catalan[i]%mod)%mod; 49 } 50 printf("%I64d\n", ans); 51 } 52 53 int main(void){ 54 int T; 55 scanf("%d", &T); 56 Init(); 57 58 while(T--){ 59 int n; 60 scanf("%d", &n); 61 62 solve(n); 63 } 64 65 return 0; 66 }