BZOJ 2822[AHOI2012]树屋阶梯 卡特兰数+高精

Posted TS_Hugh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 2822[AHOI2012]树屋阶梯 卡特兰数+高精相关的知识,希望对你有一定的参考价值。

这道题随便弄几个数就发现是卡特兰数然而为什么是呢?

我们发现我们在增加一列时,如果这一个东西(那一列)他就一格,那么就是上一次的方案数,并没有任何改变,他占满了也是,然后他要是占两格呢,就是把原来的切成了n-2,和1,要是就剩一格呢,也是把原来的切成一格和n-2,因为如果一行的某一列被堵了那么这一行的开头的那个台阶表面就覆盖不到那一列.....

这个是从数学角度,由于递推公式的相似性所以是卡特兰数.......

#include <cstdio>
const int STD=10000;
struct Bigint{
  int a[405];
  inline friend Bigint operator * (Bigint A,int B);
  inline void operator *= (int B){
    *this=(*this)*B;
  }
  inline void print(){
    printf("%d",a[a[0]]);
    for(int i=a[0]-1;i>0;i--)
      printf("%04d",a[i]);
  }
}ans;
inline Bigint operator * (Bigint A,int B){
  int x=0;
  for(int i=1;i<=A.a[0];i++){
    A.a[i]=A.a[i]*B+x;
    x=A.a[i]/STD;
    A.a[i]%=STD;
  }
  if(x)A.a[++A.a[0]]=x;
  return A;
}
const int N=1001;
int prime[N],len,size[N],MMin[N];
bool isnot[N];
inline void get_prime(){
  for(int i=2;i<N;i++){
    if(!isnot[i]){
      prime[++len]=i;
      MMin[i]=len;
    }
    for(int j=1;j<=len&&prime[j]*i<N;j++){
      isnot[prime[j]*i]=1;
      MMin[prime[j]*i]=j;
      if(i%prime[j]==0){
        break;
      }
    }
  }
}
inline void get_(int x,int d){
  while(x!=1){
    size[MMin[x]]+=d;
    x/=prime[MMin[x]];
  }
}
int main(){
  get_prime();
  int n;
  ans.a[0]=ans.a[1]=1;
  scanf("%d",&n);
  for(int i=n<<1;i>n+1;i--)
    get_(i,1);
  for(int i=1;i<=n;i++)
    get_(i,-1);
  for(int i=1;i<=len;i++){
    while(size[i])
      ans*=prime[i],size[i]--;
  }
  ans.print();
  return 0;
}

 

以上是关于BZOJ 2822[AHOI2012]树屋阶梯 卡特兰数+高精的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2822: [AHOI2012]树屋阶梯

bzoj 3907 网格 bzoj2822 [AHOI2012]树屋阶梯——卡特兰数(阶乘高精度模板)

BZOJ 2822[AHOI2012]树屋阶梯 卡特兰数+高精

2822. [AHOI2012]树屋阶梯卡特兰数

题解 P2532 [AHOI2012]树屋阶梯

[AHOI2012]树屋阶梯