XDOJ1146 - 组合数学五之Fate zero

来源:互联网 发布:linux cpu控制 编辑:程序博客网 时间:2024/04/29 03:57
描述:
Fate是讲述这一场围绕着圣杯而展开的战斗。在战斗中的七个参与者可以召唤出一个历史上的英雄,来为自己战斗。不过这样有很多弊端,比如说会引发一些历史遗留问题(兰斯洛特见到亚瑟王什么的,项羽见到刘邦什么的…………)。而且有时还会引发不必要的误会,比如下面一例:
 
最近,吉尔.德.莱斯一直缠着亚瑟王,而且还说他是圣女贞德再世,以此引发了一系列的骚扰。终于有一天,亚瑟王忍无可忍了,决定去讨伐莱斯。作为一个小有名气的法师,莱斯的保护措施是很完善的。
他有m面不同颜色的每条边均不等的n边凸边形的魔法盾。亚瑟王的每一次攻击都是将一个凸多边形延其某个对角线斩开,使其变为两个凸多边形。当在一种颜色的凸多边形的魔法盾中只有三角形时,就会变得能量不稳定,这时只要消灭其中一个三角形,这种颜色的能量盾就会消失。问:亚瑟王如果要完全破处莱斯的防御有多少种不同的方式?(斩击无先后顺序的区别)

 

Input
每一行有一个m,n(3<n<10^18,1<=m<10^18)
Output
每一行输出一个可能的放法数(模10007取余)
Sample Input
1 3
2 4
Sample Output
1
4
解题思路:

== 分析 ==

 考虑1块n边形魔法盾的情况, 设有cata[n]种分割成三角形的办法,则答案为cata[n],当有m个魔法盾时,每个都有cata[n]种办法,所以答案为cata[n]的m次幂

这里的cata[n]就属于卡塔兰数列,具体地说n边形的三角形剖分方案数是卡塔兰数列的第n-2项.

== 卡塔兰数 ==

 公式为c(2*n,n)/(n+1), 考虑到求模的问题这个形式很不方便, 可以展开成c(n,2*n)-c(n+1,2*n) (通过顶端链接可以查到),将组合数按定义展开,略作计算就能达到. 卡塔兰数的通项公式可以利用它的递归性质,通过生成函数得到,具体可以参考<<The art and craft of problem solving>>  (中文名:怎样解题,不是波利亚那部,图书馆就有,不过要等我先还......囧)  卡塔兰数有很多奇妙的性质,诞生出很多经典问题,有必要深入了解,传说有本名为<<具体数学>>的奇书记载着卡塔兰数的组合证明,有缘的话30就能买到=。=...

== 卢卡斯定理 ==

 本题需要对组合数求模,当n取某些值时,不与模数p互素,无法求其逆元,需要利用卢卡斯定理.
#include<iostream>using namespace std;const int P = 10007;long long fastPow(long long x,long long y,int p){    long long ans = 1;    while(y)    {        if(y&1)            ans = ans*x%p;        y >>= 1;        x = x*x%p;    }    return ans;}long long factorial[P+1];void init(long long p){    factorial[0] = 1;    for(int i = 1;i <= p;i++)        factorial[i] = factorial[i-1]*i%p;}long long Lucas(long long a,long long k,long long p) //求C(n,m)%p p最大为10^5。a,b可以很大!{    long long re = 1;    while(a && k)    {        long long aa = a%p;long long bb = k%p;        if(aa < bb) return 0;        re = re*factorial[aa]*fastPow(factorial[bb]*factorial[aa-bb]%p,p-2,p)%p;//这儿的求逆不可先处理        a /= p;        k /= p;    }    return re;}long long getCatan(long long n){    return (Lucas(2*n,n,P)-Lucas(2*n,n+1,P)+P)%P;}int main(){    long long n,m;    init(P);    while(cin>>m>>n)    {        m %=(P-1);        n = getCatan(n-2);        cout<<fastPow(n,m,P)<<endl;    }    return 0;}


0 0
原创粉丝点击