【BZOJ】1485: [HNOI2009]有趣的数列
【算法】Catalan数
【题解】
学了卡特兰数就会啦>_<!
因为奇偶各自递增,所以确定了奇偶各自的数字后排列唯一。
那么就是给2n个数分奇偶了,是不是有点像入栈出栈序呢。
将做偶数标为-1,做奇数标为+1,显然当偶数多于奇数时不合法,因为它压不住后面的奇数。
然后其实这种题目,打表就可知啦……QAQ
然后问题就是求1/(n+1)*C(2n,n)%p了,p不一定是素数。
参考bzoj礼物的解法。
看到网上清一色的素数筛+分解质因数解法,思考了好久,感觉写了假的礼物……
后来试了一下发现礼物的做法慢得多,原因应该是礼物解法复杂度O(min(n,P))而且常数大,分解质因数O(n),但我觉得也带常数呀?
很奇怪……不过反正n太大只能用礼物的做法,不大的话分解质因数应该更快。
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f,maxn=; ll n,P,m,p[],pc[],M[],a[];
ll num,fac[maxn];
ll power(ll x,ll k,ll p)
{
ll ans=;
while(k>)
{
if(k&)ans=ans*x%p;
x=x*x%p;
k>>=;
}
return ans;
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b){x=;y=;return;}
else {exgcd(b,a%b,y,x);y-=x*(a/b);}
}
ll inv(ll x,ll p)
{
ll xx,yy;
exgcd(x,p,xx,yy);
return ((xx%p)+p)%p;
}
ll calc(ll x,ll p,ll pc)
{
if(x<p)return fac[x];
num+=x/p;
return fac[x%pc]*power(fac[pc-],x/pc,pc)%pc*calc(x/p,p,pc)%pc;
}
ll work(ll p,ll pc)
{
fac[]=;
for(ll i=;i<min(pc,*n+);i++)fac[i]=fac[i-]*(i%p==?:i)%pc;
num=;
ll n1=calc(*n,p,pc);
ll tmp=num;
for(ll i=;i<min(pc,*n+);i++)fac[i]=fac[i-]*(i%p==?:inv(i,pc))%pc;
num=;
ll n2=calc(n,p,pc)*calc(n,p,pc)%pc;
ll np=n+;
while(np%p==){num++;np/=p;}
n2=n2*inv(np,pc)%pc;
return n1*n2*power(p,tmp-num,pc)%pc;
} int main()
{
scanf("%lld%lld",&n,&P);
m=;ll nowP=P;
for(ll i=;i*i<=nowP&&nowP>;i++)
{
if(nowP%i==){p[++m]=i;pc[m]=;}
while(nowP%i==){pc[m]*=i;nowP/=i;}
}
if(nowP>){p[++m]=nowP;pc[m]=nowP;}
ll ans=;
for(ll i=;i<=m;i++)
{
M[i]=P/pc[i];
a[i]=work(p[i],pc[i]);
ans=(ans+a[i]*M[i]%P*inv(M[i],pc[i])%P)%P;
}
printf("%lld",(ans%P+P)%P);//答案一定要记得取非负
return ;
}
礼物的做法
【BZOJ】1485: [HNOI2009]有趣的数列的更多相关文章
- 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)所 ...
- BZOJ 1485: [HNOI2009]有趣的数列
Description 求长度为 \(2n\) 的序列.要求 1. \(a_1<a_3<a_5<...<a_{2n-1}\) . 2. \(a_2<a_4<a_6& ...
- bzoj 1485 [HNOI2009]有趣的数列 卡特兰数
把排好序的序列看成一对对括号,要把他们往原数列里塞,所以就是括号序合法方案数 即为卡特兰数 f(n)=Cn2nn+1 求的时候为避免除法,可以O(n)计算每个素数出现次数,最后乘起来,打完之后发现其实 ...
- bzoj1485: [HNOI2009]有趣的数列(Catalan数)
1485: [HNOI2009]有趣的数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 2105 Solved: 1117[Submit][Stat ...
- 【BZOJ1485】[HNOI2009]有趣的数列(组合数学)
[BZOJ1485][HNOI2009]有趣的数列(组合数学) 题面 BZOJ 洛谷 题解 从小往大填数,要么填在最小的奇数位置,要么填在最小的偶数位置. 偶数位置填的数的个数不能超过奇数位置填的数的 ...
- BZOJ_1485_[HNOI2009]有趣的数列_卡特兰数
BZOJ_1485_[HNOI2009]有趣的数列_卡特兰数 Description 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ ...
- [HNOI2009]有趣的数列 题解(卡特兰数)
[HNOI2009]有趣的数列 Description 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满 ...
- [HNOI2009]有趣的数列 卡特兰数
题面:[HNOI2009]有趣的数列 题解: 观察到题目其实就是要求从长为2n的序列中选n个放在集合a,剩下的放在集合b,使得集合a和集合b中可以一一对应的使a中的元素小于b. 2种想法(实质上是一样 ...
随机推荐
- PAT 甲级 1027 Colors in Mars
https://pintia.cn/problem-sets/994805342720868352/problems/994805470349344768 People in Mars represe ...
- PHP 多文件打包下载 zip
<?php $zipname = './photo.zip'; //服务器根目录下有文件夹public,其中包含三个文件img1.jpg, img2.jpg, img3.jpg,将这三个文件打包 ...
- phaser的小游戏的onInputDown问题
group.inputEnableChildren = true; for (var i = 0; i < 10; i++) { var sprite = group.crea ...
- 第187天:js基础---常见的Bom对象
BOM(Browser Object Mode)浏览器对象模型,是Javascript的重要组成部分.它提供了一系列对象用于与浏览器窗口进行交互,这些对象通常统称为BOM. 一张图了解一下先 1.wi ...
- solr4.2增量索引之同步(修改,删除,新增)--转载
原文地址:http://www.jiancool.com/article/12743229775/;jsessionid=14E9B3F1BB33399799884B5C8F15DDE1 solr增 ...
- 【bzoj4695】最假女选手 线段树区间最值操作
题目描述 给定一个长度为 N 序列,编号从 1 到 N .要求支持下面几种操作:1.给一个区间[L,R] 加上一个数x 2.把一个区间[L,R] 里小于x 的数变成x 3.把一个区间[L,R] 里大于 ...
- MethodHandle
JDK7为间接调用方法引入新的API,在java.lang.invoke包下,可以看作为反射的升级版,但它不像反射API那样显得冗长.繁重 主要的类 MethodHandle 方法句柄.对可直接执行的 ...
- 深入理解JVM一类加载器原理
我们知道我们编写的java代码,会经过编译器编译成字节码文件(class文件),再把字节码文件装载到JVM中,映射到各个内存区域中,我们的程序就可以在内存中运行了.那么字节码文件是怎样装载到JVM中的 ...
- 连接Mysql数据库
JDBC连接数据库 创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.la ...
- bzoj3173
Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input 第一行一 ...