HDU3240题解
来源:互联网 发布:即时消息软件 编辑:程序博客网 时间:2024/05/17 05:16
分析:一看就知道是卡特兰数
卡特兰数的公式:
令h(0)=1,h(1)=1,catalan数满足递推式[1] :
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + … + h(n-1)h(0) (n>=2)
例如:h(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2
h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5
另类递推式[2] :
h(n)=h(n-1)*(4*n-2)/(n+1);
递推关系的解为:
h(n)=C(2n,n)/(n+1) (n=0,1,2,…)
递推关系的另类解为:
h(n)=c(2n,n)-c(2n,n-1)(n=0,1,2,…)
这道题目用到了第二个递推式,赛场上记不到也没问题 记住形状
h[n] = h[n-1] * (a * n - b) / (n + c) abc枚举一下就出来了。
这题难点还是求逆元,因为有分母取模,而且m和i+1不一定互质。
所以分开考虑,因素分解m,然后得到m的素因子 记入map中,每次分解i+1的时候,判断这个因子是不是在map中出现过就行了。出现过记录,没出现过的部分就是和m互质的部分直接相乘取模就行了
//// Created by Matrix on 2015-12-20// Copyright (c) 2015 Matrix. All rights reserved.//////#pragma comment(linker, "/STACK:102400000,102400000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <sstream>#include <set>#include <vector>#include <stack>#define ALL(x) x.begin(), x.end()#define INS(x) inserter(x, x,begin())#define ll long long#define CLR(x) memset(x, 0, sizeof x)using namespace std;const int inf = 0x3f3f3f3f;const int MOD = 1e9 + 7;const int maxn = 1e5 + 10;const int maxv = 1e3 + 10;const double eps = 1e-9;ll extended_gcd(ll a, ll b, ll &x, ll &y, ll& mod) { if (b == 0) { x = 1; y = 0; return a; } else { ll gcd = extended_gcd(b, a % b, x, y, mod); ll t = x % mod; x = y % mod; y = ((t - a/b*x) % mod + mod) % mod; return gcd; }}ll num[maxn];map <ll, ll> mp, vis;map <ll, ll>::iterator iter;ll fac[maxn], top;void DivNum(ll n) { top = 0; for(ll i = 2; i * i <= n; i++) { if(n % i == 0) { fac[top] = i; num[top] = 0; while(n % i == 0) { n /= i; num[top]++; } top++; } } if(n != 1) { fac[top] = n; num[top++] = 1; }}int main() {#ifdef LOCAL freopen("in.txt", "r", stdin);// freopen("out.txt","w",stdout);#endif// dp[0] = dp[1] = 1;// for(int i = 2; i <= 1e5; i++) {// dp[i] = dp[i-1] * (4 * i - 2) / (i + 1);// } ll n, m; while(scanf("%lld%lld", &n, &m) != EOF && (n + m)) { if(m == 1) {puts("0"); continue;} mp.clear(); vis.clear(); ll st = 1 % m; ll ans = st; DivNum(m); for(int i = 0; i < top; i++) { vis[fac[i]]++; } for(ll i = 2; i <= n; i++) { ll u = i * 4 - 2; ll d = i + 1; DivNum(u); for(int j = 0; j < top; j++) { if(vis.count(fac[j])) { while(num[j]) { u /= fac[j]; num[j]--; mp[fac[j]]++; } } } DivNum(d); for(int j = 0; j < top; j++) { if(vis.count(fac[j])) { while(num[j]) { d /= fac[j]; num[j]--; mp[fac[j]]--; } if(mp[fac[j]] == 0) mp.erase(fac[j]); } } ll x, y; extended_gcd(d, m, x, y, m); st = st * u % m * x % m; ll tmp = st; for(iter = mp.begin(); iter != mp.end(); iter++) { ll p = iter -> second; ll ss = 1; while(p--) { ss = ss * (iter -> first) % m; } tmp = tmp * ss % m; }// printf("st = %lld\n", tmp); ans = (ans + tmp) % m; } cout << ans << endl; } return 0;}
0 0
- HDU3240题解
- hdu3240 Counting Binary Trees 卡特兰数 乘法逆元
- HDU3240-Counting Binary Trees(Catalan数+求逆元(非互质))
- HDU3240 Counting Binary Trees (卡特兰数,拓欧求逆元)
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解~~~~
- 题解。。。。
- 题解
- java线程——什么是线程?
- 算法之6-回溯法解数独问题
- 使用boost的库链接问题generic_category()
- Jenkins权限配置失误后导致登录失败的解决办法
- C++类型转换
- HDU3240题解
- RTL的实现
- EF--ORM
- SharedPreferences保存数据
- EXT4磁盘组织 - EXT4文件系统分析 1
- [Leetcode]Bulb Switcher
- poj 1466 && hdu 1068Girls and Boys(最大独立集)
- 一些adb的口令
- 【Linux 驱动】netfilter/iptables (三) 注册和注销Netfilter hook