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个卡特兰数,从大神那盗取了一份模板,效率极高.同时也很复杂.
#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(大卡特兰数)的更多相关文章
- HOJ 13101 The Triangle Division of the Convex Polygon(数论求卡特兰数(模不为素数))
The Triangle Division of the Convex Polygon 题意:求 n 凸多边形可以有多少种方法分解成不相交的三角形,最后值模 m. 思路:卡特兰数的例子,只是模 m 让 ...
- 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是在输入中给的,所 ...
- [LeetCode] Convex Polygon 凸多边形
Given a list of points that form a polygon when joined sequentially, find if this polygon is convex ...
- Leetcode: Convex Polygon
Given a list of points that form a polygon when joined sequentially, find if this polygon is convex ...
- ACM训练联盟周赛 G. Teemo's convex polygon
65536K Teemo is very interested in convex polygon. There is a convex n-sides polygon, and Teemo co ...
- 【LeetCode】469. Convex Polygon 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 计算向量夹角 日期 题目地址:https://leet ...
- HDU 5914 Triangle(打表——斐波那契数的应用)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5914 Problem Description Mr. Frog has n sticks, whos ...
- HDU 4195 Regular Convex Polygon
思路:三角形的圆心角可以整除(2*pi)/n #include<cstdio> #include<cstring> #include<iostream> #incl ...
- POJ 3410 Split convex polygon(凸包)
题意是逆时针方向给你两个多边形,问你这两个多边形通过旋转和平移能否拼成一个凸包. 首先可以想到的便是枚举边,肯定是有一对长度相同的边贴合,那么我们就可以n2枚举所有边对,接下来就是旋转点对,那么假设多 ...
随机推荐
- Linux命令权限 用户权限 组权限 文件、目录权限
Linux命令的格式是: 命令+选项+参数 命令是必须存在的,选项和参数可以不必存在,不写的情况是有默认的参数 Linux 一切皆文件 对于文件而言,只需要对文件进行读写就可以实现对文件内容内容的增删 ...
- ios 自定义RadioButton
1 前言 众所周知在IOS中没有单选按钮这一控件,今天我们来学习一下简单的单选控件.类似与Web中的radio表单元素. 2 详述 本控件单纯的利用按钮控件和NSObject的respondsToSe ...
- vue表单验证:vee-validate中文提示
官方文档:https://baianat.github.io/vee-validate/guide/ vee-validate可用于vue项目中进行表单验证,使用方法在官方API上都可以查到: 使用过 ...
- MySQL-简要说明
分类 安装发展顺序分为: 网状型数据库 层次型数据库 关系型数据库 面向对象数据库 主流:关系型数据库 关系型数据库 事务transaction: 多个操作被当作一个整体对待 • ACID: ...
- 如何创作用纯 CSS 绘制一支栩栩如生的铅笔
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/PaZYBw 可交互视频教 ...
- CSS3-文本-text-shadow
一.text-shadow 语法: text-shadow : none | <length> none | [<shadow>, ] * <shadow> 或no ...
- SQL server的GO用法--巨坑
SQL脚本是一种用SQL语言写的批处理文件(.sql),SQL脚本通常可以由SQL查询分析器来执行. ================================================= ...
- [Redis]ResponseError: Client sent AUTH, but no password is set
由于在代码中给redis添加了密码,如下 redis_store = redis.Redis(host='localhost', port=6379, db=4, password='root') 然 ...
- 关于Powershell执行时的问题
问题1: [问题描述] 使用Invoke-Command命令登录远程主机执行命令时,提示如下错误: [192.168.1.135] 连接到远程服务器失败,错误消息如下: WinRM 客户端无法处理该请 ...
- MFC中关于CListBox控件添加水平滚动条
首先是设置listbox控件的属性 Horizontal Scroll设为TRUE: 然后添加函数到CUighurRecognitionDlg.cpp(在CUighurRecognitionDlg. ...