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\n", combinationModFac(2 * (n-2), n-2, k));
169     return 0;
170 }
时间: 2024-10-14 09:39:58

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

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

The Triangle Division of the Convex Polygon 题意:求 n 凸多边形可以有多少种方法分解成不相交的三角形,最后值模 m. 思路:卡特兰数的例子,只是模 m 让人头疼,因为 m 不一定是素数,所以不一定存在逆元. 解法:式子为f(n) =  ( C( 2*(n-2),  (n-2) ) / (n-1))   % m :令 p = n-2, 式子可化为:f(p) = ((2*p)! / ( p! * (p+1)! ) ) % m; 对 s!分解质因素,统计个

hunnu11562:The Triangle Division of the Convex Polygon(第n个卡特兰数取模)

Problem description   A convex polygon with n edges can be divided into several triangles by some non-intersect diagonals. We denote d(n) is the number of the different ways to divide the convex polygon. For example,when n is 6,there are 14 different

HNU 13101 The Triangle Division of the Convex Polygon 卡特兰数第n项%m(m可为非素数

题目链接:点击打开链接 首先要n-=2,然后就是一个卡特兰数了. 上一题用的是 h(n) = h(n-1) * (4n-2)/(n+1); 这题用的是 h(n) = (2n)! * n! / (n+1)!; 然后对阶乘分解质因数: 点击打开链接 分解完了直接快速幂. #include<stdio.h> #include<iostream> #include<cmath> #include<cstring> using namespace std; #defi

[LeetCode] Convex Polygon 凸多边形

Given a list of points that form a polygon when joined sequentially, find if this polygon is convex (Convex polygon definition). Note: There are at least 3 and at most 10,000 points. Coordinates are in the range -10,000 to 10,000. You may assume the

Leetcode: Convex Polygon

Given a list of points that form a polygon when joined sequentially, find if this polygon is convex (Convex polygon definition). Note: There are at least 3 and at most 10,000 points. Coordinates are in the range -10,000 to 10,000. You may assume the

LeetCode469 - Convex Polygon - Medium (Python)

Given a list of points that form a polygon when joined sequentially, find if this polygon is convex (Convex polygon definition). [[0,0],[0,1],[1,1],[1,0]] Answer: True [[0,0],[0,10],[10,10],[10,0],[5,5]] Answer: False 思路:这题问的是给一系列polygon的点,判断其是否是conv

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

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5914 Problem Description Mr. Frog has n sticks, whose lengths are 1,2, 3?n respectively. Wallice is a bad man, so he does not want Mr. Frog to form a triangle with three of the sticks here. He decides t

Spoj-TRNGL Make Triangle

Make Triangle Chayanika loves Mathematics. She is learning a new chapter geometry. While reading the chapter a question came in her mind. Given a convex polygon of n sides. In how many ways she can break it into triangles, by cutting it with (n-3) no

HDU6219/POJ1259 [ICPC2017沈阳]Empty Convex Polygons 最大空凸包

Empty Convex Polygons Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 538    Accepted Submission(s): 138 Problem Description Given a set of distinct points S on a plane, we define a convex ho