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. POI读word doc 03 文件的两种方法

    Apache poi的hwpf模块是专门用来对word doc文件进行读写操作的.在hwpf里面我们使用HWPFDocument来表示一个word doc文档.在HWPFDocument里面有这么几个 ...

  2. mysql 复制中的 paxso 的两阶段和事务两阶段的区别

    1.普通的两阶段是 推送不同的数据给不同的主机,一旦出现网络中断,造成问题是不可服务. 因为本身有锁,故无所谓. 2.paxos 的两阶段是将相同的 数据给不同的主机,一旦超过半数即可认为成功.

  3. VUE2中axios的使用方法

    一,安装 npm install axios 二,在http.js中引入 import axios from 'axios'; 三,定义http request 拦截器,添加数据请求公用信息 axio ...

  4. 【dp 状态压缩 单调栈】bzoj3591: 最长上升子序列

    奇妙的单调栈状压dp Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个 ...

  5. RestTemplate进行表单请求,注意要使用MultiValueMap

    在对接API的时候,有时候文档中会说,表单提交,这时候就需要用到 MultiValueMap来操作,下面给大家展示一个简单的demo. MultiValueMap<Object, Object& ...

  6. (25)zabbix事件通知

    概述 我们前面花了大量时间去讲解item.trigger.event都是为发送报警做准备的,什么是事件通知呢?简单的说故障发生了,zabbix会发邮件或者短信给你,告诉你服务器的一些状况. 如果没有通 ...

  7. 如何利用 CSS 动画原理,在页面上表现日蚀现象

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OELvrK 可交互视频教 ...

  8. js的弹性运动

    弹性: 速度+=(目标点-当前值)/系数://系数大概可以选择6,7,8 速度*=摩擦系数://系数可以选择0.7,0.75,0.8 缓冲: 速度=(目标点-当前值)/系数: 速度取整:

  9. Linux服务器的弱口令检测及端口扫描

    一.弱口令检测--John the Ripper John the Ripper工具可以帮助我们扫描出系统中密码安全性较低的用户,并将扫描后的结果显示出来. 1.安装John the Ripper: ...

  10. django第七天(模板的复用性,include标签和母版)

    django第7天模板 include标签 模板的共用 a 模板需要到使用到 登陆界面 b 模板需要使用到 登陆界面 可以把登陆界面提取到公共的模板c 为什么要用: 都需要使用相同的界面,减少代码冗余 ...