[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)所 ...
随机推荐
- UVALive 6862 Triples (找规律 暴力)
Triples 题目链接: http://acm.hust.edu.cn/vjudge/contest/130303#problem/H Description http://7xjob4.com1. ...
- MacOS下Java Mission Control无法正常启动
参考JMC(Java Mission Control)在mac下无法启动和显示界面 附件下载地址备份(org.eclipse.swt.cocoa.macosx.x86_64-3.112.0.jar) ...
- Python编程:从入门到实践—列表
访问列表中的元素 >>> bicycles = ['trek','cannondale','redline','specialized']>>> print(bic ...
- qbzt day1 上午
内容提要 模拟,贪心 在讲这些东西之前,我们先来了解一个东西:high level 这个东西大体上就是你做题之前要先想清楚自己要写什么,怎么写,然后再写,不要有一点写一点 1.模拟 模拟算法算是很水的 ...
- win10蓝屏1
win10一直蓝屏. 事件查看里有系统错误提示 DCOM部分组件错误,表现为:应用程序-特定 权限设置并未向在应用程序容器 不可用 SID (不可用)中运行的地址 LocalHost (使用 LRPC ...
- H5 刮图-刮一刮
<!DOCTYPE html><html><head><style>*{margin:0;padding:0} </style></h ...
- 【Unity Shader】---Alpha Blending的意义
Alpha Blending 即Alpha混合 Blending 就是处理透明度的,处理光栅化最后阶段,显示在屏幕上的颜色 1 Blend Off 关闭alpha混合 2 混合公式:Blend Src ...
- js 一道题目引发的正则的学习
正则表达式中的特殊字符 字符 含意 \ 做为转意,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/\b/,转意为匹配一个 ...
- 028 (H5*) 商城实战
目录: 正文: 1:创建项目 介绍 ESlintESLint 是一个ECMAScript/JavaScript 语法规则和代码风格的检查工具,它的目标是保证代码的一致性和避免错误. utit test ...
- 2019寒假作业三:PTA7-1抓老鼠啊~亏了还是赚了
- 抓老鼠啊~亏了还是赚了? ( 分) 某地老鼠成灾,现悬赏抓老鼠,每抓到一只奖励10元,于是开始跟老鼠斗智斗勇:每天在墙角可选择以下三个操作:放置一个带有一块奶酪的捕鼠夹(T),或者放置一块奶酪(C ...