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 = , y = , 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 = ;
  20. while(k)
  21. {
  22. if(k&) res *= x;
  23. x *= x, k >>= ;
  24. }
  25. return res;
  26. }
  27. typec powerMod(typec x, typec k, typec m)
  28. {
  29. typec res = ;
  30. while(x %= m, k)
  31. {
  32. if(k&) res *= x, res %= m;
  33. x *= x, k >>= ;
  34. }
  35. return res;
  36. }
  37. typec inverse(typec a, typec p, typec t = )
  38. {
  39. typec pt = power(p, t);
  40. typec x, y;
  41. y = extendGCD(a, pt, x, y);
  42. return x < ? 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 < ) x += p * q;
  50. return x;
  51. }
  52. const int PRIMEMAX = ;
  53. int prime[PRIMEMAX + ];
  54. int getPrime()
  55. {
  56. memset(prime, , sizeof(int) * (PRIMEMAX + ));
  57. for(int i = ; i <= PRIMEMAX; i++)
  58. {
  59. if(!prime[i]) prime[++prime[]] = i;
  60. for(int j = ; j <= prime[] && prime[j] <= PRIMEMAX/i; j++)
  61. {
  62. prime[prime[j]*i] = ;
  63. if(i % prime[j] == ) break;
  64. }
  65. }
  66. return prime[];
  67. }
  68. int factor[][], facCnt;
  69. int getFactors(int x)
  70. {
  71. facCnt = ;
  72. int tmp = x;
  73. for(int i = ; prime[i] <= tmp / prime[i]; i++)
  74. {
  75. factor[facCnt][] = , factor[facCnt][] = ;
  76. if(tmp % prime[i] == )
  77. factor[facCnt][] = prime[i];
  78. while(tmp % prime[i] == )
  79. factor[facCnt][]++, factor[facCnt][] *= prime[i], tmp /= prime[i];
  80. if(factor[facCnt][]) facCnt++;
  81. }
  82. if(tmp != ) factor[facCnt][] = tmp, factor[facCnt][] = tmp, factor[facCnt++][] = ;
  83. return facCnt;
  84. }
  85. typec combinationModPt(typec n, typec k, typec p, typec t = )
  86. {
  87. if(k > n) return ;
  88. if(n - k < k) k = n - k;
  89. typec pt = power(p, t);
  90. typec a = , b = k + , x, y;
  91. int pcnt = ;
  92. while(b % p == ) pcnt--, b /= p;
  93. b %= pt;
  94. for(int i = ; i <= k; i++)
  95. {
  96. x = n - i + , y = i;
  97. while(x % p == ) pcnt++, x /= p;
  98. while(y % p == ) pcnt--, y /= p;
  99. x %= pt, y %= pt, a *= x, b *= y;
  100. a %= pt, b %= pt;
  101. }
  102. if(pcnt >= t) return ;
  103. extendGCD(b, pt, x, y);
  104. if(x < ) x += pt;
  105. a *= x, a %= pt;
  106. return a * power(p, pcnt) % pt;
  107. }
  108. const typec PTMAX = ;
  109. typec facmod[PTMAX];
  110. void initFacMod(typec p, typec t = )
  111. {
  112. typec pt = power(p, t);
  113. facmod[] = % pt;
  114. for(int i = ; i < pt; i++)
  115. {
  116. if(i % p) facmod[i] = facmod[i - ] * i % pt;
  117. else facmod[i] = facmod[i - ];
  118. }
  119. }
  120. typec factorialMod(typec n, typec &pcnt, typec p, typec t = )
  121. {
  122. typec pt = power(p, t), res = ;
  123. typec stepCnt = ;
  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 - ], stepCnt, pt);
  130. return res %= pt;
  131. }
  132. typec combinationModPtFac(typec n, typec k, typec p, typec t = )
  133. {
  134. if(k > n || p == ) return ;
  135. if(n - k < k) k = n - k;
  136. typec pt = power(p, t), pcnt = , pmcnt = ;
  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 <<= , b %= pt;
  142. typec tmp = k + ;
  143. while(tmp % p == ) tmp /= p, pmcnt++;
  144. b *= tmp % pt, b %= pt;
  145. pcnt -= pmcnt;
  146. if(pcnt >= t) return ;
  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 = ; i < facCnt; i++)
  155. {
  156. if(!i) a = combinationModPtFac(n, k, factor[i][], factor[i][]), p = factor[i][];
  157. else b = combinationModPtFac(n, k, factor[i][], factor[i][]), q = factor[i][];
  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\n", combinationModFac( * (n-), n-, k));
  169. return ;
  170. }

HUNAN 11562 The Triangle Division of the Convex Polygon(大卡特兰数)的更多相关文章

  1. HOJ 13101 The Triangle Division of the Convex Polygon(数论求卡特兰数(模不为素数))

    The Triangle Division of the Convex Polygon 题意:求 n 凸多边形可以有多少种方法分解成不相交的三角形,最后值模 m. 思路:卡特兰数的例子,只是模 m 让 ...

  2. HNU 13101 The Triangle Division of the Convex Polygon 组合数的因式分解求法

    题意: 求第n-2个Catalan数 模上 m. 思路: Catalan数公式: Catalan[n] = C(n, 2n)/(n+1) = (2n)!/[(n+1)!n!] 因为m是在输入中给的,所 ...

  3. [LeetCode] Convex Polygon 凸多边形

    Given a list of points that form a polygon when joined sequentially, find if this polygon is convex ...

  4. Leetcode: Convex Polygon

    Given a list of points that form a polygon when joined sequentially, find if this polygon is convex ...

  5. ACM训练联盟周赛 G. Teemo's convex polygon

    65536K   Teemo is very interested in convex polygon. There is a convex n-sides polygon, and Teemo co ...

  6. 【LeetCode】469. Convex Polygon 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 计算向量夹角 日期 题目地址:https://leet ...

  7. HDU 5914 Triangle(打表——斐波那契数的应用)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5914 Problem Description Mr. Frog has n sticks, whos ...

  8. HDU 4195 Regular Convex Polygon

    思路:三角形的圆心角可以整除(2*pi)/n #include<cstdio> #include<cstring> #include<iostream> #incl ...

  9. POJ 3410 Split convex polygon(凸包)

    题意是逆时针方向给你两个多边形,问你这两个多边形通过旋转和平移能否拼成一个凸包. 首先可以想到的便是枚举边,肯定是有一对长度相同的边贴合,那么我们就可以n2枚举所有边对,接下来就是旋转点对,那么假设多 ...

随机推荐

  1. github更换仓库

    1.找到.git目录   2.打开config文件 3.修改仓库地址 4.重新提交 git push --all origin 这样就替我们的项目换仓啦!!!^_^   分类: git 参考资料: h ...

  2. 菜鸟教你如何通俗理解——>集群、负载均衡、分布式

    在“高并发,海量数据,分布式,NoSql,云计算......”概念满天飞的年代,相信不少朋友都听说过甚至常与人提起“集群,负载均衡”等,但不是所有人都有机会真正接触到这些技术,也不是所有人都真正理解了 ...

  3. springboot上传linux文件无法浏览,提示404错误

    1.配置文件地址置换 @Componentclass WebConfigurer implements WebMvcConfigurer { @Autowired ConfigUtil bootdoC ...

  4. 简单的Redis数据迁移

    dump迁移 1.安装redis-dump工具 sudo apt-get install ruby rubygems ruby-devel -y gem sources --add http://ge ...

  5. 【Linux】VirtualBox虚拟网络配置

    Host OS : Windows 10 Guest OS : CentOS 6.8 VirtualBox:5.1.18 网络连接方式: NAT 1.CentOS中使用DHCP [root@gouka ...

  6. Vue—事件修饰符

    Vue事件修饰符 Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation(). Vue. ...

  7. DOM事件模型浅析

    1.何为DOM DOM是"Document Object Model"的缩写,中文译为"文档对象模型".它是一种跨平台.跨语言的编程接口,将HTML,XHTML ...

  8. css3的border-radius属性使用方法

    1.border-radius可以包含两个参数值,第一个水平圆角半径,第二个为垂直半径,并且两个参数值用“/”分开. 2.border-radius:设置一个值为四个角都相同,两个值为左上和右下相同, ...

  9. 我的Python分析成长之路8

    Numpy数值计算基础 Numpy:是Numerical Python的简称,它是目前Python数值计算中最为基础的工具包,Numpy是用于数值科学计算的基础模块,不但能够完成科学计算的任而且能够用 ...

  10. 如何完整反编译AndroidMainfest.xml

    下载工具: http://code.google.com/p/android4me/downloads/detail?name=AXMLPrinter.zip&can=2&q= 包名为 ...