【卡特蘭數+高精度】hdu3723
阿新 • • 發佈:2021-09-16
本來想要複習卡特蘭數沒想到卡在高精度卡了好久好久5555~~~
我們很容易發現這是一道卡特蘭數板子題。然後對於平走的處理就是不計入卡特蘭考慮就可以了。設h[k] = C(n,2*k)*kat[k],那麼答案就是sigma(k:0-->n/2) h[k]。
對於式子推一推發現h[k] = h[k-1] * (n-2*k+1) * (n-2*k+2) / ( k * (k+1) )。
之後我們用壓位高精度模擬一下就可以了。
高精度的一些提醒:時刻注意函式直接傳遞的指標的話要小心他可能隨時是變的。還有就是高精度乘的時候一定要先乘,然後考慮是否可能會有多步進位!
點選檢視程式碼
#include<iostream> #include<algorithm> #include<cstring> #include<stack> #include<bitset> #include<queue> #include<vector> #include<cstdio> #include<set> #include<map> #include<cmath> using namespace std; typedef long long ll; const ll yaw = 100000; struct gjd{ int len; ll a[10000]; //5*20 //0-->19 useful }A,ANS; void mul(gjd &x,ll y) { for(int i=0;i<=x.len;i++) x.a[i]*=y; for(int i=0;i<=x.len;i++) { if(x.a[i]>=yaw) { x.a[i+1] += x.a[i]/yaw; x.a[i]%=yaw; } if(x.a[x.len+1]) x.len++; } } void div(gjd &x,ll y) { ll o = 0; for(int i=x.len;i>=0;i--) { ll oo = x.a[i]; x.a[i] = (o*yaw+oo)/y; o = (o*yaw+oo)%y; } while(x.len&&(!x.a[x.len])) x.len--; } void pint(gjd &x) { if(x.len<=19) { printf("%lld",x.a[x.len]); for(int i=x.len-1;i>=0;i--) { printf("%05lld",x.a[i]); } } else { cerr<<"fuck"; printf("%lld",x.a[19]); for(int i=18;i>=0;i--) { printf("%05lld",x.a[i]); } } } void ADD(gjd &x,gjd &y) { int le = max(x.len,y.len); for(int i=0;i<=le;i++) { x.a[i] += y.a[i]; x.a[i+1] += x.a[i]/yaw; x.a[i] %= yaw; } x.len = le; while(x.a[x.len+1]) x.len++; } int main(){ /* A.a[0] = 11; mul(A,300000); ANS.len = 2; ANS.a[2] = 3; ADD(A,ANS); pint(A); */ A.a[0]=1; ANS.a[0]=1; ll n; scanf("%lld",&n); for(ll i=1;i*2<=n;i++) { ll cf = (n-2*i+1ll)*(n-2*i+2ll); mul(A, cf); div(A,i*(i+1)); ADD(ANS,A); } pint(ANS); return 0; }