zoukankan      html  css  js  c++  java
  • 【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;
    }
  • 相关阅读:
    promise的终止调用方法:
    (五)浅谈测试用例
    (四)一个bug的生命周期
    (三)趣谈软件需求分析
    (二)软件测试分类
    (一) 软件测试实质
    【转载—“光荣之路”公众号】Bug预防体系(上千bug分析后总结的最佳实践)
    <MFC>FILE的操作
    <CAN>测试的原理
    <C++>消息循环
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7363030.html
Copyright © 2011-2022 走看看