uestc 1554 Counting Binary Trees (catalan 数)

来源:互联网 发布:人工智能发展趋势作文 编辑:程序博客网 时间:2024/06/05 08:57


此题 上一题的升级版 。。

数据规模变大, 还要mod 一个数 。

递推公式  Cn+1 = Cn * (4n + 2) / ( n + 2)


由于 有除法 还要取模  ,那么 就要求逆元,但是给定的m 不一定和 (n+2) 互质,不能直接求 逆元,那么 就要吧 N+2 中的 和 m 相同的因子提出来 特别计算就可以。

#include <cstdio>  #include <cstring>  #include <iostream>    using namespace std;  int n , m;  #define LL long long     int p[25];  int num[25];  int tot;  void init_p(){      tot = 0;      int t = m;      memset(num,0,sizeof(num));      for(int i=2 ;i*i<= t;i++){          if(t%i==0){              tot ++;              p[tot] = i;              while(t%i == 0 ){                  t = t/i;              }          }      }      if(t>1){          tot ++ ;          p[tot] = t;      }  }  int f(int a){      int  ans = 1;      for(int i=2 ;i*i<= a;i++){          if(a%i== 0){              ans *= i -1;              a /= i;              while(a%i==0){                  ans *= i;                  a /= i;              }          }      }      if(a > 1){          ans *= a-1;      }      return ans;  }  LL pow(LL a,LL b){      LL ans = 1;      while(b){          if(b&1){              ans *= a;              ans %= m;          }          a = a*a ;          a%= m;          b>>=1;      }      return ans;  }  void solve(){      LL sum = 1;      LL ans = 1;      int t = f(m);      for(int i=2;i<=n;i++){          int a = 4*(i-1) +2;          int b = (i-1) + 2;          for(int j=1;j<=tot;j++){              while(a%p[j]== 0){                  num[j]++;                  a /= p[j];              }          }          for(int j=1;j<= tot;j++){              while(b%p[j] == 0){                  num[j]--;                  b/= p[j];              }          }          ans *= a;          ans %= m;          ans *= pow(b,t-1);          ans %= m;          LL tmp = ans;           for(int i=1;i<= tot;i++){              if(num[i]){                  tmp *= pow(p[i],num[i]);                  tmp %= m;              }          }          sum += tmp ;          sum %= m;      }      printf("%d\n",(int)sum%m);  }  int main(){      while(~scanf("%d%d",&n,&m)){          if(n == 0 && m ==0 ) break;          init_p();          solve();      }  }    




原创粉丝点击