当前位置: 首页 > web >正文

洛谷 P1375:小猫 ← 预处理模逆元 + 卡特兰数

【题目来源】
https://www.luogu.com.cn/problem/P1375

【题目描述】
有 2n 只小猫
站成一圈,主人小明想把它们两两之间用绳子绑住尾巴连在一起。同时小明是个完美主义者,不容许看到有两根绳子交叉。请问小明有几种连线方案,可以把让所有小猫两两配对?
方案数很大,仅需输出方案数模 10^9+7(一个质数)的值。

【输入格式】
输入共一行,一个整数 n。

【输出格式】
输出方案数对
10^9+7 取模后的值。

【输入样例】
3

【输出样例】
5

【数据范围】
对于 60% 的数据,1≤N≤100。
对于 100% 的数据,1≤N≤10^5。

【算法分析】
(一)预处理 1~n 的模 p 逆元‌(详见:
https://blog.csdn.net/hnjzsyjyj/article/details/147778571
若在竟赛中需
频繁计算 1, 2, …, n 的逆元,也可以用“逆元预处理“技巧。其可以仅需 O(n) 时间得到所有值的逆元。
● 预处理 1~n 的模 p 逆元‌的理论证明

定理:inv[i]=(p-p/i)*inv[p%i]%p,其中 p 为质数。
证明:设 k=p/i,r=p%i,则有 p=k*i+r
两边模 p 得:k*i+r≡0 (mod p) → i≡-r/k (mod p)
因此,inv[i]≡-k*inv[r] (mod p)。
之后,利用公式 (p+x%p)%p 将 inv[i]≡-k*inv[r] (mod p) 调整为对应的正数:
inv[i]=(p-k*inv[r]%p)%p=(p-(p/i)*inv[p%i]%p)%p。
由于 p≡0 (mod p),故 (p-(p/i)*inv[p%i]%p)%p 可简化为:−(p/i)*inv[p%i]%p
又根据模运算性质 -x≡p-x(mod p),
所以,−(p/i)*inv[p%i]%p 等价于 (p−(p/i)*inv[p%i])%p=(p−p/i)*inv[p%i]%p
综上,得证。

● 预处理 1~n 的模 p 逆元‌的模板代码:inv[i]=(p-p/i)*inv[p%i]%p

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const int N=3e6+5;
LL inv[N];int main() {LL n,p;scanf("%lld %lld",&n,&p);inv[1]=1;for(int i=2; i<=n; i++) {inv[i]=(p-p/i)*inv[p%i]%p;}for(int i=1; i<=n; i++) {printf("%lld\n",inv[i]);}return 0;
}/*
in:
10 13out:
1
7
9
10
8
11
2
5
3
4
*/

(二)快速幂(详见:https://blog.csdn.net/hnjzsyjyj/article/details/143168167
● 快速幂的模板代码

#include <bits/stdc++.h>
using namespace std;typedef long long LL;int fastPow(LL a,LL b,LL p) {LL ans=1;while(b) {if(b & 1) ans=ans*a%p;a=a*a%p;b>>=1;}return ans%p;
}int main() {int a,b,p;int T;cin>>T;while(T--) {cin>>a>>b>>p;cout<<fastPow(a,b,p)<<endl;}return 0;
}/*
in:
2
3 2 5
4 3 9out:
4
1
*/

(三)卡特兰数
● 卡特兰数(
Catalan number)是组合数学中一个常出现在各种计数问题中的数列。若从第 0 项开始,则卡特兰数列 h[n] 为:1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, …。其中,常用的卡特兰数列 h[n] 有如下 4 种等价的递推式:
h[n]=
h[0]*h[n−1]+h[1]*h[n−2]+...+h[n−1]*h[0], (n≥2, h[0]=h[1]=1)
h[n]=
h[n−1]*(4*n−2)/(n+1), (n≥2)
h[n]=C(2n,n)−C(2n,n−1), (n=0,1,2,...)
h[n]=C(2n,n)/(n+1), (n=0,1,2,...)

● 卡特兰数的模板代码一

依据递推式 h[n]=h[n−1]*(4*n−2)/(n+1), (n≥2) 编码。

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const int maxn=1e5+5;
LL h[maxn];
LL n;int main() {scanf("%lld",&n);h[0]=1,h[1]=1;for(int i=2; i<=n; i++) {h[i]=h[i-1]*(4*i-2)/(i+1);}for(int i=0; i<=n; i++) {printf("%lld ",h[i]);}return 0;
}/*
in:6
out:1 1 2 5 14 42 132
*/

● 卡特兰数的模板代码二
依据递推式 h[n]=h[0]*h[n−1]+h[1]*h[n−2]+...+h[n−1]*h[0], (n≥2, h[0]=h[1]=1) 编码。

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const int maxn=1e5+5;
LL h[maxn];
LL n;int main() {scanf("%lld",&n);h[0]=1,h[1]=1;for(int i=2; i<=n; i++) {for(int j=0; j<=i-1; j++) {h[i]+=h[j]*h[i-j-1];}}for(int i=0; i<=n; i++) {printf("%lld ",h[i]);}return 0;
}/*
in:6
out:1 1 2 5 14 42 132
*/

【算法代码】

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const int p=1e9+7;
const int maxn=1e5+5;
LL h[maxn],inv[maxn];
int n;int main() {scanf("%d",&n);inv[1]=1;for(int i=2; i<=n+1; i++) {inv[i]=(p-p/i)*inv[p%i]%p;}h[0]=h[1]=1;for(int i=2; i<=n; i++) {h[i]=h[i-1]*(4*i-2)%p*inv[i+1]%p;}printf("%lld",h[n]);return 0;
}/*
in:3
out:5
*/




【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/145842440
https://blog.csdn.net/hnjzsyjyj/article/details/129148916
https://www.luogu.com.cn/problem/U140713
https://www.luogu.com.cn/problem/P1375
https://www.luogu.com.cn/problem/P1976
​​​​​​https://www.luogu.com.cn/problem/P1044

https://www.luogu.com.cn/problem/P1641
https://blog.csdn.net/zsyz_ZZY/article/details/80418515





 

http://www.xdnf.cn/news/6743.html

相关文章:

  • nacos配置文件快速部署另一种方法
  • 第十天——贪心算法——深度总结
  • 提高表达能力
  • FC7300 DMA MCAL 配置引导
  • idea 中引入python
  • 无人设备遥控器的信号传输与抗干扰技术
  • 动态图标切换的艺术
  • 软件架构风格系列(1):分层架构如何让系统“稳如泰山”?
  • AI 笔记 -基于retinaface的FPN上采样替换为CARAFE
  • Android framework 中间件开发(一)
  • 149.WEB渗透测试-MySQL基础(四)
  • 【暗光图像增强】【基于CNN的方法】2020-AAAI-EEMEFN
  • 显性知识的主要特征
  • math.js 加/减/乘/除 使用
  • 第九天——贪心算法——非递减数组
  • ZYNQ Overlay硬件库使用指南:用Python玩转FPGA加速
  • AWS中国区CloudFront证书管理和应用指南
  • 五月月报丨MaxKB在教育行业的应用进展与典型场景
  • 现代简约中式通用,民国画报风,中国风PPT模版8套一组分享
  • 【Vue 3全栈实战】从响应式原理到企业级架构设计
  • 数据结构(3)线性表-链表-单链表
  • k8s监控方案实践补充(二):使用kube-state-metrics获取资源状态指标
  • 前端开发笔记与实践
  • Visual Studio 2022 中添加“高级保存选项”及解决编码问题
  • WebMvcConfigurer介绍-笔记
  • GESP2025年3月认证C++二级( 第三部分编程题(2)时间跨越)
  • MongoDB 应用实战
  • 多尺度对比度调整
  • DDD领域驱动介绍
  • MODBUS RTU调试助手使用方法详解