hdu4828(卡特兰数+逆元)

2024-09-09 17:38
文章标签 卡特兰 逆元 hdu4828

本文主要是介绍hdu4828(卡特兰数+逆元),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这题的前几个数据分别为1,2,5,14,32......................然后确定这是个卡特兰数列

下面来介绍下卡特兰数,它的递推式为f[i+1] = f[i]*(4*n - 6)/n,其中f[2] = f[3] =1;f[4] = 2;f[5] = 14;f[6] = 32..................................

但是这题的n太大了,所以要用到逆元,这里除以一个数,就相当于乘以一个数的逆元。

代码如下(附注释):

#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
#include<math.h>#define ll long long
#define N 1000010
#define MOD 1000000007
#define inf 0x7fffffff
#define eps 1e-9
#define pi acos(-1.0)
#define P system("pause")
using namespace std;
ll f[N];void exgcd(ll a,ll b,ll& d, ll &x, ll &y)//扩展欧几里得算法,模板
{if(!b) {d = a; x = 1; y = 0;}else{exgcd(b,a%b,d,y,x);y -= x*(a/b);}
}ll inv(ll a, ll n)//求a模n的逆元,也是模板
{ll d, x, y;exgcd(a,n,d, x, y);return d == 1 ? (x+n)%n : -1;
}int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);ios::sync_with_stdio(false);ll i;f[3] = 1;//f[4] = 2;for(i = 3; i < N-5; i++){f[i+1] = (4*i-6)%MOD;f[i+1] = f[i+1]*f[i]%MOD;ll k = inv(i,MOD);f[i+1] = (f[i+1]*k)%MOD;}ll t, z = 1;cin>>t;while(t--){ll n;cin>>n;printf("Case #%d:\n",z++);cout<<f[n+2]<<endl;}return 0;
}


这篇关于hdu4828(卡特兰数+逆元)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1151839

相关文章

hdu4869(逆元+求组合数)

//输入n,m,n表示翻牌的次数,m表示牌的数目,求经过n次操作后共有几种状态#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#includ

每日一题~cf 970 div3 (A思维,B小模拟,C二分,D排列数建图成环,E 26个字母暴力+前缀和,F 逆元,G 数论gcd )

A 题意: 有 a 个1 ,b 个2.问是否能将这些数划分为两个数值相等的集合。 输出 YES 或者 NO —————— 问题等价于 将数组 分成两个数值相同的数组。所以sum 应该是偶数。也就是说 1 的个数是偶数。在i1的个数是偶数的情况下,将 2 分成两份,如果2 的个数是偶数,OK。如果是奇数那么需要1来补齐,如果1 的个数大于等于2那么可以补齐。(1 的个数是偶数,需要2个1来补齐,剩下

HDU 1130(卡特兰数,大数)

题意:如题。   import java.util.*;import java.math.*;public class Main{public static void main(String[] args) {int n;Scanner in=new Scanner(System.in);BigInteger one=BigInteger.ONE;BigInteger four

排列数+时间戳+逆元取模

前言:这个题目是真的难,不会做,看了题解才发现是咋回事 题目地址 最主要的就是为啥是除以3,c之前需要完成a 和 b,d 和 e 对我们的答案没有影响,所以我们要除以 A(3,3) ,但是 a 和 b 的排列没有要求,所以乘以 A( 2 , 2 ) 抵消得到 3 #include<bits/stdc++.h>using i64 = long long;using u64 =

Codeforces Round #295 (Div. 1) C. Pluses everywhere (组合数学+乘法逆元)

这题可以这样想:       对于当前第i位来说,该位若在个位上出现,那么第i位和第i+1位中间肯定有一个“+”,剩下的k-1个“+”分布在剩下的n-2个空隙中,所以出现的总次数是C(n-2,k)。同理,在十位上出现的总次数是C(n-3,k)。于是每个数字的贡献值就可以求出来了,累加即可。       所以大体思路是遍历所有可能出现的位数,从个位开始,分成两部分计算,一部分用前缀和计算出前面所

hdu 2067 小兔的棋盘 (卡特兰数的应用)

/******************* Author:fisty* Data:2014-10-19* hdu 2067*****************/#include <cstdio>#include <algorithm>using namespace std;long long f[110];//卡特兰数int main(){f[0]=1;for(int i=1;i<=35;i

数论 —— 逆元与同余式定理

【同余模公式】 (A+B)%M = (A%M+B%M) % M(A*B)%M = (A%M*B%M) % M(A/B)%M = (A*C)%M = (A%M*C%M) % M,其中 B*C≡1(mod M),B、M 互质,C 称为 B 的逆元 (A/B)%M 的推导:(A/B)%M = (A/B) * 1 % M = (A/B)*B*C % M = (A*C) % M 【威尔逊定理】 若

UVa 991 Safe Salutations 卡特兰数

题目来源:UVa 991 Safe Salutations 题意:圆上2*n个点均匀分布 两两相连 求不相交的方案数 思路:卡特兰数的应用 以下总结转自某大牛 /*最典型的四类应用:(实质上却都一样,无非是递归等式的应用,就看你能不能分解问题写出递归式了)1.括号化问题。矩阵链乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化

同余式,乘法逆元,费马小定理

同余式 同余式是 数论 的基本概念之一,设m是给定的一个正整数,a、b是整数,若满足m| (a-b),则称a与b对模m 同余 ,记为a≡b (mod m),或记为a≡b (m)。 这个式子称为模m的同余式,若m∤ (a-b),则称a、b对模m不同余 同余概念又常表达为: 1.a=b+km (k∈Z); 2.a和b被m除时有相同的 余数  乘法逆元 乘法逆元的定义:在数学领域,对于群G

uva 10303 - How Many Trees?(卡特兰数)

题目链接:uva 10303 - How Many Trees? 卡特兰数,公式num[i + 1] = num[i] * (4 * i - 6) / i ( i ≥ 3)。 #include <stdio.h>#include <string.h>#include <iostream>using namespace std;const int N = 6005;str