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

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

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

 #include <cstdio>
#include <cmath>
#include <stdlib.h>
#include <memory.h>
typedef int typec;
typec GCD(typec a, typec b)
{
return b? GCD(b, a % b) : a;
}
typec extendGCD(typec a, typec b, typec& x, typec& y)
{
if(!b) return x = , y = , a;
typec res = extendGCD(b, a % b, x, y), tmp = x;
x = y, y = tmp -(a/b)*y;
return res;
}
typec power(typec x, typec k)
{
typec res = ;
while(k)
{
if(k&) res *= x;
x *= x, k >>= ;
}
return res;
}
typec powerMod(typec x, typec k, typec m)
{
typec res = ;
while(x %= m, k)
{
if(k&) res *= x, res %= m;
x *= x, k >>= ;
}
return res;
}
typec inverse(typec a, typec p, typec t = )
{
typec pt = power(p, t);
typec x, y;
y = extendGCD(a, pt, x, y);
return x < ? x += pt : x;
}
typec linearCongruence(typec a, typec b, typec p, typec q)
{
typec x, y;
y = extendGCD(p, q, x, y);
x *= b - a, x = p * x + a, x %= p * q;
if(x < ) x += p * q;
return x;
}
const int PRIMEMAX = ;
int prime[PRIMEMAX + ];
int getPrime()
{
memset(prime, , sizeof(int) * (PRIMEMAX + ));
for(int i = ; i <= PRIMEMAX; i++)
{
if(!prime[i]) prime[++prime[]] = i;
for(int j = ; j <= prime[] && prime[j] <= PRIMEMAX/i; j++)
{
prime[prime[j]*i] = ;
if(i % prime[j] == ) break;
}
}
return prime[];
}
int factor[][], facCnt;
int getFactors(int x)
{
facCnt = ;
int tmp = x;
for(int i = ; prime[i] <= tmp / prime[i]; i++)
{
factor[facCnt][] = , factor[facCnt][] = ;
if(tmp % prime[i] == )
factor[facCnt][] = prime[i];
while(tmp % prime[i] == )
factor[facCnt][]++, factor[facCnt][] *= prime[i], tmp /= prime[i];
if(factor[facCnt][]) facCnt++;
}
if(tmp != ) factor[facCnt][] = tmp, factor[facCnt][] = tmp, factor[facCnt++][] = ;
return facCnt;
}
typec combinationModPt(typec n, typec k, typec p, typec t = )
{
if(k > n) return ;
if(n - k < k) k = n - k;
typec pt = power(p, t);
typec a = , b = k + , x, y;
int pcnt = ;
while(b % p == ) pcnt--, b /= p;
b %= pt;
for(int i = ; i <= k; i++)
{
x = n - i + , y = i;
while(x % p == ) pcnt++, x /= p;
while(y % p == ) pcnt--, y /= p;
x %= pt, y %= pt, a *= x, b *= y;
a %= pt, b %= pt;
}
if(pcnt >= t) return ;
extendGCD(b, pt, x, y);
if(x < ) x += pt;
a *= x, a %= pt;
return a * power(p, pcnt) % pt;
}
const typec PTMAX = ;
typec facmod[PTMAX];
void initFacMod(typec p, typec t = )
{
typec pt = power(p, t);
facmod[] = % pt;
for(int i = ; i < pt; i++)
{
if(i % p) facmod[i] = facmod[i - ] * i % pt;
else facmod[i] = facmod[i - ];
}
}
typec factorialMod(typec n, typec &pcnt, typec p, typec t = )
{
typec pt = power(p, t), res = ;
typec stepCnt = ;
while(n)
{
res *= facmod[n % pt], res %= pt;
stepCnt += n /pt, n /= p, pcnt += n;
}
res *= powerMod(facmod[pt - ], stepCnt, pt);
return res %= pt;
}
typec combinationModPtFac(typec n, typec k, typec p, typec t = )
{
if(k > n || p == ) return ;
if(n - k < k) k = n - k;
typec pt = power(p, t), pcnt = , pmcnt = ;
if(k < pt) return combinationModPt(n, k, p, t);
initFacMod(p, t);
typec a = factorialMod(n, pcnt, p, t);
typec b = factorialMod(k, pmcnt, p, t);
b *= b, pmcnt <<= , b %= pt;
typec tmp = k + ;
while(tmp % p == ) tmp /= p, pmcnt++;
b *= tmp % pt, b %= pt;
pcnt -= pmcnt;
if(pcnt >= t) return ;
a *= inverse(b, p, t), a %= pt;
return a * power(p, pcnt) % pt;
}
typec combinationModFac(typec n, typec k, typec m)
{
getFactors(m);
typec a, b, p, q;
for(int i = ; i < facCnt; i++)
{
if(!i) a = combinationModPtFac(n, k, factor[i][], factor[i][]), p = factor[i][];
else b = combinationModPtFac(n, k, factor[i][], factor[i][]), q = factor[i][];
if(!i) continue;
a = linearCongruence(a, b, p, q), p *= q;
}
return a;
}
int main()
{
getPrime();
typec n, k;
while(scanf("%d %d", &n, &k) != EOF)
printf("%d\n", combinationModFac( * (n-), n-, k));
return ;
}

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. urllib2功能说明

    1.urlopen(url, data, timeout) 第一个参数url即为URL,第二个参数data是访问URL时要传送的数据,第三个timeout是设置超时时间. 第二三个参数是可以不传送的, ...

  2. CPP-基础:关于内存分配

    1:c中的malloc和c++中的new有什么区别 (1)new.delete 是操作符,可以重载,只能在C++中使用.(2)malloc.free是函数,可以覆盖,C.C++中都可以使用.(3)ne ...

  3. nyoj-47-过河问题|POJ-1700-Crossing River

    http://acm.nyist.net/JudgeOnline/problem.php?pid=47 http://poj.org/problem?id=1700 解题思路:求最少需要多少时间才能都 ...

  4. 第2节 azkaban调度:1、azkaban的调度任务使用

    2.4 Azkaban实战 Azkaba内置的任务类型支持command.java Command类型单一job示例 创建job描述文件 创建文本文件,更改名称为mycommand.job 注意后缀. ...

  5. Bootstrap历练实例:带有下拉菜单的标签和胶囊导航

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  6. bootstrap历练实例: 导航元素中禁用的链接

    对每个 .nav class,如果添加了 .disabled class,则会创建一个灰色的链接,同时禁用了该链接的 :hover 状态, <!DOCTYPE html><html& ...

  7. iOS 面试集锦

    是第一篇: 1.Difference between shallow copy and deep copy?
浅复制和深复制的区别?
答案:浅层复制:只复制指向对象的指针,而不复制引用对象本身.
深层 ...

  8. 常用JavaScript正则表达式整理

    在表单验证中,正则表达式书写起来特别繁琐,本文整理了15个常用的JavaScript正则表达式,其中包括用户名.密码强度.整数.数字.电子邮件地址(Email).手机号码.身份证号.URL地址. IP ...

  9. 全排列问题(DFS)

    题目描述: 输出自然数1到n所有不重复的排列,即n的全排列,要求所产生的任一数字序列中不允许出现重复的数字. 输入格式: n(1≤n≤9) 输出格式: 由1-n组成的所有不重复的数字序列,每行一个序列 ...

  10. Sql语句的一些事(一)

    (1)LIMIT子句(MySql) ----LIMIT 子句用于规定要返回的记录的数目,一般和Order By一起使用 经常用于数据的分页查询,但是一旦数据量一大,limit的性能就会急速下降 格式: ...