[HNOI2009]有趣的数列(卡塔兰数,线性筛)
[HNOI2009]有趣的数列
题目描述
我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件:
(1)它是从1到2n共2n个整数的一个排列{ai};
(2)所有的奇数项满足a1<a3<...<a2n-1,所有的偶数项满足a2<a4<...<a2n;
(3)任意相邻的两项a2i-1与a2i(1<=i<=n)满足奇数项小于偶数项,即:a2i-1<a2i。
现在的任务是:对于给定的n,请求出有多少个不同的长度为2n的有趣的数列。因为最后的答案可能很大,所以只要求输出答案 mod P的值。
输入输出格式
输入格式:
输入文件只包含用空格隔开的两个整数n和P。输入数据保证,50%的数据满足n<=1000,100%的数据满足n<=1000000且P<=1000000000。
输出格式:
仅含一个整数,表示不同的长度为2n的有趣的数列个数mod P的值。
输入输出样例
输入样例#1:
3 10
输出样例#1:
5
对应的5个有趣的数列分别为(1,2,3,4,5,6),(1,2,3,5,4,6),(1,3,2,4,5,6),(1,3,2,5,4,6),(1,4,2,5,3,6)。
考试的一道题目,但是出题人改了题面,考场上写了一个记搜的暴力,然后打表发现是卡塔兰数,然而忘记取模这回事了...
后面再来看这道题的题面,除了全排列减一下枝看不出怎么写暴力。
50分代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define lll long long
using namespace std;
lll read()
{
lll x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*w;
}
lll n,p,ans;
lll dp[1000010];
lll f[2010][2010];
lll dfs(lll qian,lll zhi)
{
if(zhi==0) return 1;
if(f[qian][zhi]!=-1) return f[qian][zhi];
if(qian==0||qian==zhi)
{
f[qian][zhi]=dfs(zhi,zhi-1)%p;
return f[qian][zhi];
}
else
{
f[qian][zhi]=(dfs(qian,zhi-1)%p+dfs(qian-1,zhi)%p)%p;
return f[qian][zhi];
}
}
int main()
{
memset(f,-1,sizeof(f));
n=read();p=read();
dp[1]=1;
if(n<=2000) cout<<dfs(0,n)%p;
else
{
for(lll i=2;i<=n;i++)
{
dp[i]=(dp[i-1]*((4*i)%p-2)/(i+1))%p;
}
cout<<dp[n]%p;
}
return 0;
}
这道题的难点在于如何取模,由卡塔兰数必然是整数的性质,我们筛出数据范围内所有的质数,对于每一个和数,记录和数是由哪个质数筛出来的。将分子分母相同的质数数量直接减去,由性质,我们可以知道减出来的个数一定>=0。最后我们直接用快速幂求和即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define lll long long
using namespace std;
lll read()
{
lll x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*w;
}
lll n,p,ans;
lll pre[2000010];
lll num[2000010];
lll nop[2000010];
lll prime[500010];
lll quick_pow(lll x,lll k)
{
ans=1;
while(k)
{
if(k&1) ans=ans*x%p;
x=x*x%p;
k/=2;
}
return ans%p;
}
int main()
{
lll m=0;
n=read();p=read();
nop[1]=1;
for(lll i=2;i<=2*n;i++)
{
if(!nop[i]) {prime[++m]=i;pre[i]=i;}
for(lll j=1;j<=m,i*prime[j]<=2*n;j++)
{
nop[i*prime[j]]=1;pre[i*prime[j]]=prime[j];
if(i%prime[j]==0) break;
}
}
for(lll i=2;i<=n;i++)
{
lll ii=i;
while(ii!=1)
num[pre[ii]]--,ii/=pre[ii];
}
for(lll i=n+2;i<=2*n;i++)
{
lll ii=i;
while(ii!=1)
num[pre[ii]]++,ii/=pre[ii];
}
lll sum=1;
for(lll i=1;i<=m;i++)
{
if(num[prime[i]])
sum=(sum*quick_pow(prime[i],num[prime[i]]))%p;
}
cout<<sum%p;
}
[HNOI2009]有趣的数列(卡塔兰数,线性筛)的更多相关文章
- BZOJ_1485_[HNOI2009]有趣的数列_卡特兰数
BZOJ_1485_[HNOI2009]有趣的数列_卡特兰数 Description 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ ...
- 洛谷P3200 [HNOI2009]有趣的数列(Catalan数)
P3200 [HNOI2009]有趣的数列 题目描述 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满足 ...
- [bzoj1485][HNOI2009]有趣的数列_卡特兰数_组合数
有趣的数列 bzoj-1485 HNOI-2009 题目大意:求所有1~2n的排列满足奇数项递增,偶数项递增.相邻奇数项大于偶数项的序列个数%P. 注释:$1\le n\le 10^6$,$1\le ...
- bzoj1485: [HNOI2009]有趣的数列(Catalan数)
一眼卡特兰数...写完才发现不对劲,样例怎么输出$0$...原来模数不一定是质数= =... 第一次见到模数不是质数的求组合数方法$(n,m\leq 10^7)$,记录一下... 先对于$1$~$n$ ...
- 【题解】洛谷P3200 [HNOI2009] 有趣的数列(卡特兰数+质因数分解)
洛谷P3200:https://www.luogu.org/problemnew/show/P3200 思路 这题明显是卡特兰数的题型咯 一看精度有点大 如果递推卡特兰数公式要到O(n2) 可以证明得 ...
- [luogu1485 HNOI2009] 有趣的数列 (组合数学 卡特兰数)
传送门 Solution 卡特兰数 排队问题的简单变化 答案为\(C_{2n}^n \pmod p\) 由于没有逆元,只好用分解质因数,易证可以整除 Code //By Menteur_Hxy #in ...
- [HNOI2009]有趣的数列 题解(卡特兰数)
[HNOI2009]有趣的数列 Description 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满 ...
- BZOJ 1485: [HNOI2009]有趣的数列( catalan数 )
打个表找一下规律可以发现...就是卡特兰数...卡特兰数可以用组合数计算.对于这道题,ans(n) = C(n, 2n) / (n+1) , 分解质因数去算就可以了... -------------- ...
- BZOJ 1485: [HNOI2009]有趣的数列 [Catalan数 质因子分解]
1485: [HNOI2009]有趣的数列 Description 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所 ...
随机推荐
- C. Anna, Svyatoslav and Maps
C. Anna, Svyatoslav and Maps 给定一个有向图,给定一条有向路径,求一条顶点最少的路径,使得给定的路径是它的最短路 folyd预处理出任意两点间的最短路,然后判断是否可以缩点 ...
- 音频学习(一)-离线播放(AVAudioPlayer)
最后更新:2017-05-23 方法 - (nullable instancetype)initWithContentsOfURL:(NSURL *)url error:(NSError **)out ...
- WebServices 实现跨应用程序进行通信和跨平台进行通信
SOA ,即Service Oriented Architecture ,中文一般理解为面向服务的架构, 既然说是一种架构的话,所以一般认为 SOA 是包含了运行环境,编程模型, 架构风格和相关方法论 ...
- SQL报错:ORA-00911:无效的字符错误
转载自:https://blog.csdn.net/huangyanlong/article/details/38096469 *)ORA-00911:无效的字符错误——由编译环境下一个小错误引起.S ...
- Day3 01 枚举
枚举:关键字 enum 主要为了限定了选择范围,声明了一组相关的值类型的集合. 1.枚举类型,实质上是整整 2.如果不进行赋值操作,枚举类型从0开始递增. 3.枚举不能定义字段 属性 方法. 例如 ...
- Linux 下wdcp支持两种安装方式
wdcp支持两种安装方式1 源码编译 此安装比较麻烦和耗时,一般是20分钟至一个小时不等,具体视机器配置情况而定2 RPM包安装 简单快速,下载快的话,几分钟就可以完成源码安装(ssh登录服务器,执行 ...
- AtomicInteger 源码分析
AtomicInteger AtomicInteger 能解决什么问题?什么时候使用 AtomicInteger? 支持原子更新的 int 值. 如何使用 AtomicInteger? 1)需要被多线 ...
- KindEditor上传图片一直提示undefined
图片已经上传成功了,但是就是不在文本编辑器里显示图片,一直弹出undefined 返回的JSON都对呀!这是官网说的返回值: //成功时 { "error" : 0, " ...
- python 卡方检验例子
python 求拒绝域和卡方值 import scipy.stats as ss obs=[107,198,192,125,132,248] exp=[167]*6 #拒绝域 1%的显著水平,自由度5 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_09-基础加强_第2节 反射_11_反射_案例
student定义sleep方法 用反射+配置文件 定义配置文件 src下new file.新建 加载配置文件.Properties里面有一个load方法,可以加载.properties结尾的配置文件 ...