luogu 1375 小猫 (卡特兰数)
Posted harryhqg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu 1375 小猫 (卡特兰数)相关的知识,希望对你有一定的参考价值。
这是我做题史上摔得最惨的一道黄题,15条记录转眼化为泪水。o(╥﹏╥)o
这道题目从10.12开始尝试,随机跳题跳到了这题,一看就是卡特兰数,因为样例太像了。。
然后小心证明
这个就是catalan的式子啊,,
然后打了一发阶乘+逆元求组合数再套公式,
ll fac[N], inv[N], fi[N] ; void init() { fac[0] = fac[1] = inv[0] = inv[1] = fi[0] = fi[1] = 1 ; for (int i = 2; i < N; i++) { fac[i] = fac[i - 1] * i % MOD ; inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD ; fi[i] = inv[i] * fi[i - 1] % MOD; } } ll C(ll a, ll b){ return fac[a] * fi[b] % MOD * fi[a - b] % MOD; } int n ; int main(){ init() ; scanf("%d", &n) ; printf("%lld ", C(2 * n, n) / (n + 1)) ; }
30,就是跟暴力一样。。。
然后之后暴力改了改,还是30
于是先把暴力的$O(n^2)dp$敲了,拿了60分
开大数组,80分,TLE两个点,一想,肯定是暴力的顶峰了,。
1 #include<cstdio> 2 #include<cstdlib> 3 long long c[100010]={1,1,2}; 4 int main(){ 5 int n,i,j; 6 scanf("%d",&n); 7 for(i=3;i<=n;i++){ 8 j=0; 9 while(j<=i-1){ 10 c[i]+=c[j]*c[i-1-j]; 11 while(c[i]>=1000000007) c[i]%=1000000007; 12 j++; 13 } 14 } 15 printf("%lld",c[n]); 16 }
之后这个题目就再没碰过,直到today,11.29
发现第一个30分代码没有强转ll,改了一下,30。
发现输出答案直接除,应该转为逆元,60了
之后觉得预处理麻烦,干脆不用,60。。
放一下60分代码
1 int jc(int a) { 2 if (a == 1) return 1 ; 3 else return 1ll * a * jc(a - 1) % MOD ; 4 } 5 6 int power(int a, int b) { 7 int res = 1 ; 8 for (; b >>= 1; a = 1ll * a * a % MOD) if (b & 1) res = 1ll * res * a % MOD ; 9 return res ; 10 } 11 12 int C(int a, int b){ 13 return 1ll * jc(a) * power(jc(b), MOD - 2) % MOD * power(jc(a - b), MOD - 2) % MOD; 14 } 15 16 int n ; 17 18 int main(){ 19 scanf("%d", &n) ; 20 printf("%lld ", 1ll * C(2 * n, n) * power(n + 1, MOD - 2) % MOD) ; 21 }
发现自己C里面b和a-b没套jc,尴尬了
改完,依然60
冷静分析,发现自己快速幂写错了,自闭了。。
我怎么那么菜啊,。。。
然后就AC了
放一下最终代码:
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <bitset> 9 #include <cstdio> 10 #include <cctype> 11 #include <string> 12 #include <cstring> 13 #include <cassert> 14 #include <climits> 15 #include <cstdlib> 16 #include <iostream> 17 #include <algorithm> 18 #include <functional> 19 using namespace std ; 20 #define int long long 21 #define rep(i, a, b) for (int (i)=(a);(i)<=(b);(i)++) 22 #define Rep(i, a, b) for (int (i)=(a)-1;(i)<(b);(i)++) 23 #define REP(i, a, b) for (int (i)=(a);(i)>=(b);(i)--) 24 #define reg(i, x) for (int (i)=head[x];(i);i=e[i].next) 25 #define clr(a) memset(a,0,sizeof(a)) 26 #define Sort(a, len) sort(a + 1, a + len + 1) 27 #define Sort2(a, len, cmp) sort(a + 1, a + len + 1, cmp) 28 #define ass(a, sum) memset(a, sum, sizeof(a)) 29 30 #define ull unsigned long long 31 #define ll long long 32 #define ls ((rt) << 1) 33 #define rs ((rt) << 1 | 1) 34 #define mp make_pair 35 #define pb push_back 36 #define fi first 37 #define se second 38 #define endl ‘ ‘ 39 #define Pii pair<int, int> 40 41 const int N = 100010 ; 42 const int iinf = INT_MAX/2 ; 43 const ll linf = LLONG_MAX/2 ; 44 const int MOD = 1e9 + 7 ; 45 46 inline int read(){ 47 int X = 0,w = 0 ; 48 char ch = 0; 49 while(!isdigit(ch)) {w |= ch == ‘-‘;ch = getchar();} 50 while(isdigit(ch)) X = (X<<3) + (X<<1) + (ch ^ 48),ch = getchar(); 51 return w ? -X : X; 52 } 53 54 void write(int x){ 55 if(x < 0) putchar(‘-‘),x = -x; 56 if(x > 9) write(x / 10); 57 putchar(x%10 + ‘0‘); 58 } 59 60 int jc(int a) { 61 if (a == 1) return 1 ; 62 else return 1ll * a * jc(a - 1) % MOD ; 63 } 64 65 int power(int a, int b) { 66 int res = 1 ; 67 for (; b; b >>= 1, a = 1ll * a * a % MOD) if (b & 1) res = 1ll * res * a % MOD ; 68 return res ; 69 } 70 71 int C(int a, int b){ 72 return 1ll * jc(a) * power(jc(b), MOD - 2) % MOD * power(jc(a - b), MOD - 2) % MOD; 73 } 74 75 int n ; 76 77 signed main(){ 78 scanf("%lld", &n) ; 79 printf("%lld ", 1ll * C(2 * n, n) * power(n + 1, MOD - 2) % MOD) ; 80 } 81 82 /* 83 写代码时请注意: 84 1.是否要开Long Long?数组边界处理好了么? 85 2.特殊情况处理好了么? 86 3.做一些总比不做好。 87 4.最大值和最小值问题可不可以用二分答案? 88 5.有没有贪心策略?否则能不能dp? 89 6.实数精度有没有处理? 90 */
以上是关于luogu 1375 小猫 (卡特兰数)的主要内容,如果未能解决你的问题,请参考以下文章
Luogu P1754球迷购票问题dp/卡特兰数By cellur925