卡特兰数
Posted znsbc-13
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了卡特兰数相关的知识,希望对你有一定的参考价值。
https://blog.csdn.net/wookaikaiko/article/details/81105031
所以各种卡特兰数题做法:
打表找规律,
题表
有趣的数列,网格,树屋阶梯
大多数时候都用到高精度和分解质因数
分解质因数
#include<bits/stdc++.h> using namespace std; #define ll long long #define A 4000000 #define P 1 #define N 10 ll n,mod,num=0; ll p[A],sum[A],v[A]; void prime(ll x){ for(ll i=2;i<=x;i++){ if(!v[i]){ v[i]=i;p[++num]=i; } for(ll j=1;j<=num;j++){ if(p[j]>v[i]||i*p[j]>x) break; v[i*p[j]]=p[j]; } } } int main(){ ll ans=1; scanf("%lld%lld",&n,&mod); prime(2*n+1); for(ll i=n+2;i<=2*n;i++){ ll x=i; while(x>1){ sum[v[x]]++; x=x/v[x]; } } for(ll i=1;i<=n;i++){ ll x=i; while(x>1){ sum[v[x]]--; x=x/v[x]; } } for(ll i=1;i<=num;i++) for(ll j=1;j<=sum[p[i]];j++) ans=ans*p[i]%mod; cout<<ans<<endl; }
高精度
#include<bits/stdc++.h> using namespace std; #define A 20000 #define P 1 #define N 10 #define ll long long ll n; struct bignum { ll n[A],l; bignum(){l=1,memset(n,0,sizeof(n));} void clear(){while(l>1&&!n[l-1]) l--;} void print(){ printf("%lld",n[l-1]); for(ll i=l-2;i>=0;i--){ printf("%0*lld",P,n[i]); } printf("\n"); } bignum operator *(bignum x) const{ bignum t=*this,tep; tep.l=t.l+x.l+1; for(ll i=0;i<t.l;i++) for(ll j=0;j<x.l;i++){ tep.n[i+j]+=t.n[i]*x.n[j]; } for(ll i=0;i<tep.l;i++){ if(tep.n[i]>=N) { tep.n[i+1]+=tep.n[i]/N; tep.n[i]%=N; } } tep.clear(); return tep; } bignum operator +(bignum x)const{ bignum t=*this; if(t.l<x.l) t.l=x.l; t.l++; for(ll i=0;i<t.l;i++){ t.n[i]+=x.n[i]; if(t.n[i]>=N){ t.n[i+1]+=t.n[i]/N; t.n[i]%=N; } } t.clear(); return t; } bignum operator =(ll x){ l=0; while(x){ n[l++]=x%N; x/=N; } return *this; } bignum operator *(const ll &b){ bignum t=*this,r; r.l=0; ll g=0; for(ll i=0;i<t.l||g;i++){ ll x; if(i<t.l) x=t.n[i]*b+g; else x=g; r.n[r.l++]=x%N; g=x/N; } return r; } bignum operator /(const ll &x){ bignum t=*this,r; ll tmp=0; r.l=t.l; for(ll i=t.l-1;i>=0;i--){ tmp+=t.n[i]; if(tmp>=x){ r.n[i]=tmp/x; tmp%=x; } tmp*=N; } r.clear(); return r; } }ans,c; bignum C(ll x,ll y){ bignum tm; tm=1; for(ll i=x-y+1;i<=x;i++){ tm=tm*i; } for(ll i=2;i<=y;i++){ tm=tm/i; } return tm; } int main() { scanf("%lld",&n); ans=C(2*n,n); ans=ans/(n+1); ans.print(); }
以上是关于卡特兰数的主要内容,如果未能解决你的问题,请参考以下文章