HDOJ4828 Grids(数论)

来源:互联网 发布:生命电视台网络直播 编辑:程序博客网 时间:2024/06/09 15:55

一开始想成DP了,后来暴力打表找规律发现原来是卡特兰数列。

于是乎就变成了卡特兰数取模问题。

递推公式h[n]=h[n-1]*(4n-2)/(n+1)

公式中有除法,所以取模的时候要用到乘法逆元。

比较方便的一点是,10^9+7是质数,必定和分母(n+1)互质,所以直接用扩展欧几里得去求逆元就好了。

关于逆元的应用:

http://blog.csdn.net/moringrain/article/details/47209985


#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;typedef long long LL;const int MAXN = 1000000;LL        base = 1E9 + 7;LL ans[MAXN+5];//计算 ax+by=gcd(a,b),返回gcd值,求出xy  LL Ex_gcd(LL a, LL b, LL &x, LL &y){LL d;if (a == 0 && b == 0) return -1;// 无GCD  if (b == 0){x = 1;y = 0;return a;}d = Ex_gcd(b, a%b, y, x);y -= a / b * x;return d;}//求a关于模n的逆元,不存在返回-1  LL Mod_reverse(LL a, LL n){LL x, y, d;d = Ex_gcd(a, n, x, y);if (d == 1)return (x % n + n) % n;elsereturn -1;}void work(){LL i, inv;memset(ans,0,sizeof(ans));ans[1] = 1;for (i = 2; i <= MAXN; i++){inv = Mod_reverse(i + 1, base);ans[i] = (4 * i - 2) * ans[i - 1] % base;ans[i] = ans[i] * inv % base;}}int main(){int i, n, T;scanf("%d",&T);work();for (i = 1; i <= T; i++){scanf("%d",&n);printf("Case #%d:\n",i);printf("%I64d\n",ans[n]);}return 0;}


0 0