zoukankan      html  css  js  c++  java
  • HUNAN 11562 The Triangle Division of the Convex Polygon(大卡特兰数)

    http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11562&courseid=0

    求n边形分解成三角形的方案数。

    就是求n-2个卡特兰数,从大神那盗取了一份模板,效率极高.同时也很复杂.

      1 #include <cstdio>
      2 #include <cmath>
      3 #include <stdlib.h>
      4 #include <memory.h>
      5 typedef int typec;
      6 typec GCD(typec a, typec b)
      7 {
      8     return b? GCD(b, a % b) : a;
      9 }
     10 typec extendGCD(typec a, typec b, typec& x, typec& y)
     11 {
     12     if(!b) return x = 1, y = 0, a;
     13     typec res = extendGCD(b, a % b, x, y), tmp = x;
     14     x = y, y = tmp -(a/b)*y;
     15     return res;
     16 }
     17 typec power(typec x, typec k)
     18 {
     19     typec res = 1;
     20     while(k)
     21     {
     22         if(k&1) res *= x;
     23         x *= x, k >>= 1;
     24     }
     25     return res;
     26 }
     27 typec powerMod(typec x, typec k, typec m)
     28 {
     29     typec res = 1;
     30     while(x %= m, k)
     31     {
     32         if(k&1) res *= x, res %= m;
     33         x *= x, k >>= 1;
     34     }
     35     return res;
     36 }
     37 typec inverse(typec a, typec p, typec t = 1)
     38 {
     39     typec pt = power(p, t);
     40     typec x, y;
     41     y = extendGCD(a, pt, x, y);
     42     return x < 0? x += pt : x;
     43 }
     44 typec linearCongruence(typec a, typec b, typec p, typec q)
     45 {
     46     typec x, y;
     47     y = extendGCD(p, q, x, y);
     48     x *= b - a, x = p * x + a, x %= p * q;
     49     if(x < 0) x += p * q;
     50     return x;
     51 }
     52 const int PRIMEMAX = 1000;
     53 int prime[PRIMEMAX + 1];
     54 int getPrime()
     55 {
     56     memset(prime, 0, sizeof(int) * (PRIMEMAX + 1));
     57     for(int i = 2; i <= PRIMEMAX; i++)
     58     {
     59         if(!prime[i]) prime[++prime[0]] = i;
     60         for(int j = 1; j <= prime[0] && prime[j] <= PRIMEMAX/i; j++)
     61         {
     62             prime[prime[j]*i] = 1;
     63             if(i % prime[j] == 0) break;
     64         }
     65     }
     66     return prime[0];
     67 }
     68 int factor[100][3], facCnt;
     69 int getFactors(int x)
     70 {
     71     facCnt = 0;
     72     int tmp = x;
     73     for(int i = 1; prime[i] <= tmp / prime[i]; i++)
     74     {
     75         factor[facCnt][1] = 1, factor[facCnt][2] = 0;
     76         if(tmp % prime[i] == 0)
     77             factor[facCnt][0] = prime[i];
     78         while(tmp % prime[i] == 0)
     79             factor[facCnt][2]++, factor[facCnt][1] *= prime[i], tmp /= prime[i];
     80         if(factor[facCnt][2]) facCnt++;
     81     }
     82     if(tmp != 1) factor[facCnt][0] = tmp, factor[facCnt][1] = tmp, factor[facCnt++][2] = 1;
     83     return facCnt;
     84 }
     85 typec combinationModPt(typec n, typec k, typec p, typec t = 1)
     86 {
     87     if(k > n) return 0;
     88     if(n - k < k) k = n - k;
     89     typec pt = power(p, t);
     90     typec a = 1, b = k + 1, x, y;
     91     int pcnt = 0;
     92     while(b % p == 0) pcnt--, b /= p;
     93     b %= pt;
     94     for(int i = 1; i <= k; i++)
     95     {
     96         x = n - i + 1, y = i;
     97         while(x % p == 0) pcnt++, x /= p;
     98         while(y % p == 0) pcnt--, y /= p;
     99         x %= pt, y %= pt, a *= x, b *= y;
    100         a %= pt, b %= pt;
    101     }
    102     if(pcnt >= t) return 0;
    103     extendGCD(b, pt, x, y);
    104     if(x < 0) x += pt;
    105     a *= x, a %= pt;
    106     return a * power(p, pcnt) % pt;
    107 }
    108 const typec PTMAX = 45000;
    109 typec facmod[PTMAX];
    110 void initFacMod(typec p, typec t = 1)
    111 {
    112     typec pt = power(p, t);
    113     facmod[0] = 1 % pt;
    114     for(int i = 1; i < pt; i++)
    115     {
    116         if(i % p) facmod[i] = facmod[i - 1] * i % pt;
    117         else facmod[i] = facmod[i - 1];
    118     }
    119 }
    120 typec factorialMod(typec n, typec &pcnt, typec p, typec t = 1)
    121 {
    122     typec pt = power(p, t), res = 1;
    123     typec stepCnt = 0;
    124     while(n)
    125     {
    126         res *= facmod[n % pt], res %= pt;
    127         stepCnt += n /pt, n /= p, pcnt += n;
    128     }
    129     res *= powerMod(facmod[pt - 1], stepCnt, pt);
    130     return res %= pt;
    131 }
    132 typec combinationModPtFac(typec n, typec k, typec p, typec t = 1)
    133 {
    134     if(k > n || p == 1) return 0;
    135     if(n - k < k) k = n - k;
    136     typec pt = power(p, t), pcnt = 0, pmcnt = 0;
    137     if(k < pt) return combinationModPt(n, k, p, t);
    138     initFacMod(p, t);
    139     typec a = factorialMod(n, pcnt, p, t);
    140     typec b = factorialMod(k, pmcnt, p, t);
    141     b *= b, pmcnt <<= 1, b %= pt;
    142     typec tmp = k + 1;
    143     while(tmp % p == 0) tmp /= p, pmcnt++;
    144     b *= tmp % pt, b %= pt;
    145     pcnt -= pmcnt;
    146     if(pcnt >= t) return 0;
    147     a *= inverse(b, p, t), a %= pt;
    148     return a * power(p, pcnt) % pt;
    149 }
    150 typec combinationModFac(typec n, typec k, typec m)
    151 {
    152     getFactors(m);
    153     typec a, b, p, q;
    154     for(int i = 0; i < facCnt; i++)
    155     {
    156         if(!i) a = combinationModPtFac(n, k, factor[i][0], factor[i][2]), p = factor[i][1];
    157         else b = combinationModPtFac(n, k, factor[i][0], factor[i][2]), q = factor[i][1];
    158         if(!i) continue;
    159         a = linearCongruence(a, b, p, q), p *= q;
    160     }
    161     return a;
    162 }
    163 int main()
    164 {
    165     getPrime();
    166     typec n, k;
    167     while(scanf("%d %d", &n, &k) != EOF)
    168         printf("%d
    ", combinationModFac(2 * (n-2), n-2, k));
    169     return 0;
    170 }
  • 相关阅读:
    对vector等STL标准容器的排序操作
    Security log is full,only administrator can log on to fix the problem(安全日志满了)
    Linux vi 中搜索关键字
    Linux tar 解压缩命令
    max_size, capacity and size 的区别
    四个基数任意次数组合相加得到一个数N,求所有可能组合
    robot framework 笔记(三),RF安装
    电脑重装后 python 2 3快速安装
    python练习题(四)
    apscheduler 执行报错No handlers could be found for logger "apscheduler.executors.default
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4728299.html
Copyright © 2011-2022 走看看