卡特兰数相关公式 :

  1. \(H_n = {C_{2n}^n \over n+1)}\)
  2. \(H_n = {(4n-2)\over n+1}\times H_{n-1}\)
  3. \(H_n = C_{2n}^n - C_{2n}^{n-1}\)
  4. $ H_n = \begin{cases} \sum_{i=1}^{n} H_{i-1} H_{n-i} & n \geq 2, n \in \mathbf{N_{+}}\ 1 & n = 0, 1 \end{cases} $

因为 \(n\le 100000\) ,所以不考虑第四种,第一种和第三种种求组合数也不可以用递推来求,而用公式的话因为要预先算出阶乘和阶乘的逆元,在此题中m不保证为质数,所以也不好计算。

对于第三种,假设以及算出了\(H_{n-1}\) 那么只需要求出\({4n-2\over n+1}\) 即可

先把 m 分解质因数,然后对于分子 \(4n-2\) ,求出m分解后的质因子的所有指数,然后对于分母\(n+1\) ,也求出m分解的质因子的所有指数,前后两个指数数组相减。剩下分子和分母与m互质的部分直接求即可,保留到递推答案pre中。

综上,当前递推的答案由一个变量pre 和一个指数数组共同记录,所以在地推出当前答案之后进行累加时,还要用pre乘所有质因子

#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
typedef long long ll;
int n,m;
int cnt[N];
vector<ll> v;
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){
ll d,x,y;
exgcd(a,n,d,x,y);
return d== 1?(x+n)%n:-1;
}
void getPrime(int x){
for(int i=2;i*i<=x;i++){
if(x % i)continue;
while(x%i==0)x/=i;
v.push_back(i);
}
if(x > 1)v.push_back(x);
return;
}
int main(){
while(cin >> n >> m){
if(n == 0 && m == 0)break;
v.clear();
memset(cnt,0,sizeof cnt);
ll res = 1 % m;
ll pre = 1;
getPrime(m);//对m进行分解质因数
for(int i=2;i<=n;i++){
ll fz = 4 * i - 2, fm = i + 1;
for(int j=0;j<v.size();j++){
if(fz % v[j] == 0)
while(fz % v[j] == 0){
fz /= v[j];
cnt[j] ++;//指数++
}
}
pre = pre * fz % m;//剩余互质部分直接乘
for(int j=0;j<v.size();j++){
if(fm%v[j] == 0)
while(fm % v[j] == 0){
fm /= v[j];
cnt[j] --;//指数--
}
}
if(fm > 1) pre = pre * inv(fm,m) % m;//更新pre
ll tmp = pre;
for(int j=0;j<v.size();j++){
for(int k=1;k<=cnt[j];k++){
tmp = (tmp * v[j]) % m;//计算当前答案
}
}
res = (res + tmp) % m;
}
cout << res << endl;
}
return 0;
}

为什么不是每次直接把质因子直接计算到pre中呢,因为之后的计算中,对分母(n+1)进行分解质因数时,有可能出现不够减的情况,所以我们要一直用一个数组记录这部分和m有公因数的部分

HDU-3240(卡特兰数+分解质因数后求逆元)的更多相关文章

  1. [bzoj2822][AHOI2012]树屋阶梯 (卡特兰数+分解质因数+高精度)

    Description 暑假期间,小龙报名了一个模拟野外生存作战训练班来锻炼体魄,训练的第一个晚上,教官就给他们出了个难题.由于地上露营湿气重,必须选择在高处的树屋露营.小龙分配的树屋建立在一颗高度为 ...

  2. 将n(0<=n<=10000)的阶乘分解质因数,求其中有多少个m

    给定两个数m,n,其中m是一个素数. 将n(0<=n<=10000)的阶乘分解质因数,求其中有多少个m. 输入 第一行是一个整数s(0<s<=100),表示测试数据的组数 随后 ...

  3. HDU 4828 (卡特兰数+逆)

    HDU 4828 Grids 思路:能够转化为卡特兰数,先把前n个人标为0.后n个人标为1.然后去全排列,全排列的数列.假设每一个1的前面相应的0大于等于1,那么就是满足的序列,假设把0看成入栈,1看 ...

  4. HDU 4828 (卡特兰数+逆元)

    HDU 4828 Grids 思路:能够转化为卡特兰数,先把前n个人标为0,后n个人标为1.然后去全排列,全排列的数列,假设每一个1的前面相应的0大于等于1,那么就是满足的序列.假设把0看成入栈,1看 ...

  5. hdu 5428 The Factor 分解质因数

    The Factor  Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://bestcoder.hdu.edu.cn/contests/contest ...

  6. Buy the Ticket HDU 1133 卡特兰数应用+Java大数

    Problem Description The "Harry Potter and the Goblet of Fire" will be on show in the next ...

  7. Train Problem II HDU 1023 卡特兰数

    Problem Description As we all know the Train Problem I, the boss of the Ignatius Train Station want ...

  8. 2014年百度之星程序设计大赛 - 初赛(第一轮) hdu Grids (卡特兰数 大数除法取余 扩展gcd)

    题目链接 分析:打表以后就能发现时卡特兰数, 但是有除法取余. f[i] = f[i-1]*(4*i - 2)/(i+1); 看了一下网上的题解,照着题解写了下面的代码,不过还是不明白,为什么用扩展g ...

  9. HDU 1023(卡特兰数 数学)

    题意是求一列连续升序的数经过一个栈之后能变成的不同顺序的数目. 开始时依然摸不着头脑,借鉴了别人的博客之后,才知道这是卡特兰数,卡特兰数的计算公式是:a( n )  =  ( ( 4*n-2 ) / ...

随机推荐

  1. 【基础】1001_Hello,World!

    题目相关 [题目描述] 编写一个能够输出"Hello,World!"的程序,这个程序常常作为一个初学者接触一门新的编程语言所写的第一个程序,也经常用来测试开发.编译环境是否能够正常 ...

  2. 【JDBC核心】数据库事务

    数据库事务 概述 事务是逻辑上的一组操作,或者说一个独立的工作单元.事务内的语句,要么全部执行成功,要么全部执行失败. 事务处理 数据一旦提交,就不可回滚.数据意味着提交的情况: 当一个连接对象被创建 ...

  3. Educational Codeforces Round 102 (Rated for Div. 2)

    比赛地址 A(水题) 题目链接 题目: 给出一个数组\(a\)并能进行一个操作使得数组元素更改为数组任意其他两元素之和,问是否可以让数组元素全部小于等于\(d\) 解析: 排序后判断最大值是否小于等于 ...

  4. 微信小程序API交互的自定义封装

    目录 1,起因 2,优化成果 3,实现思路 4,完整代码 1,起因 哪天,正在蚂蚁森林疯狂偷能量的我被boss叫过去,告知我司要做一个线上直播公开课功能的微信小程序,博主第一次写小程序,复习了下文档, ...

  5. MySQL sql命令行操作数据库

    数据库命令行操作 命令行操作数据库, [if exists] 可加可不加, 命令行操作一定要加英文分号 ; 结尾 创建数据库 : create database [if not exists] 数据库 ...

  6. xtrabackup 备份与恢复

    书上摘抄 ---深入浅出mysql 448页  grant reload on *.* to 'backup'@'localhost' identified by '123456'; grant re ...

  7. 【MYSQL】win7安装mysql-5.7.10绿色版

    1.下载 :mysql下载地址 2.解压缩 3.环境变量配置 MYSQL_HOME=D:\mysql-5.7.11-win32 PATH=%MYSQL_HOME%\bin 4.修改配置文件 a.)将m ...

  8. JAVA编程中button按钮,actionlistener和mouseClicked区别

    在java的编程中,对于按钮button 有两个事件: 1.actionPerformed 2.mouseClicked 区别: actionPerformed:一般事件,仅侦听鼠标左键的单击事件,右 ...

  9. 知识图谱KnowledgeGraph核心技术培训班 2月03日— 2月06日

  10. 深度学习DeepLearning技术实战(12月18日---21日)

    12月线上课程报名中 深度学习DeepLearning(Python)实战培训班 时间地点: 2020 年 12 月 18 日-2020 年 12 月 21日 (第一天报到 授课三天:提前环境部署 电 ...