Problem:  

  n个人(偶数)排队,排两行,每一行的身高依次递增,且第二行的人的身高大于对应的第一行的人,问有多少种方案。mod 1e9+9

Solution:

  这道题由1,2,5,14 应该想到Catalan数,但是我却花了两个小时去找递推式。

  首先 Catalan数 :

  基本规律:1,2,5,14,42,132,..........

典型例题:

  1、多边形分割。一个多边形分为若干个三角形有多少种分法。

    C(n)=∑(i=2...n-1)C(i)*C(n-i+1)

  2、排队问题:转化为n个人在第一行为0,第二行为1,则n个人的序列中,在1前面的所有0,1中,0的个数一定要大于1。

        见:http://blog.csdn.net/vast_sea/article/details/8173362      。类似于下一个问题。

  3、出入栈问题:问出入栈的方案数。

    与上一个问题相似,转换为0 为入栈,1为出栈,则合法的出入栈方案有多少?

  4,、括号匹配问题:n对括号有多少种匹配方式?类似于出入栈。

  5、二叉树问题:n个节点的二叉树有多少种形式?

     用T(i,j)表示 左节点 i 个,右节点 j 个。则根节点一定有一个,所以形式数为:T(0,n-1),T(1,n-2),T(2,n-3)....

     f[n]=f[0]*f[n-1]+f[1]*f[n-2]+.....+f[n]*f[0]

其次,Catalan数问题解决后,我们用C(n)=C(n-1)*(4*n-2)/(n-1)求解(不要问我哪里来的,我也不知道)。然后就会发现一个问题:

  A/BmodP 在数据大的情况下可能会出错,而A/BmodP肯定不等于AmodP/BmodP,这时就需要用到 逆元 了。

逆元:

  ax≡1(mod P)    ->  ax mod P=1 mod P = 1  ->    b/a*(ax) mod P == b/a mod P==b*x mod P

即 x 为a mod P的逆元。

求逆元的方式:

  1、扩展欧几里得:

    因为ax≡1(mod P),所以ax-1=nP,即ax-1为P的倍数。所以移项得:ax-nP=1。然后由扩展欧几里得算法推出x的解。

    扩展欧几里得算法推导:

      设 ax1+by1=gcd(a,b)    ∵gcd(a,b)=gcd(b,a%b)   ∴bx2+(a%b)y2=ax1+by1

      ∵a%b=a-(a/b)*b   ∴bx2+ay2-(a/b)*b*y2=ax1+by1

      根据恒等定理:x1=y2;  y1=x2-(a/b)*y2

    这样我们可以用递归求解,直到 b==0,x=1,y=0。递归x2,y2求x1,y1.

 代码:

void gcd(ll a,ll b,ll &d,ll &x,ll &y)
{
if (b==){
d=;x=;y=;
}
else {
gcd(b,a%b,d,y,x);y-=x*(a/b);//注意这里的y,x的区别,在递归的过程中,已经交换了x和y,所以为y-=x*(a/b);
}
}

  2、费马小定理:

    a^(p-1)≡1(mod P)

    则: a*a^(p-2)≡1(mod P)

    逆元:ax≡1(mod P),则x为a^(p-2),x为a mod P的逆元。可以由快速幂求得,但是如果数据大就太慢。

 代码:

ll ksm(ll x)//快速幂
{
ll tmp=x,t=,k=P-;
while (k>){
if (k%) t=(t*tmp)%P;
k=k>>;
tmp=(tmp*tmp)%P;
}
return t;
}
void pre()
{
inv[]=;
for (int i=;i<=N;i++)//费马小定理求 逆
inv[i]=ksm(i);
}

  这样,就可以A 了这道题。顺带复习了很多数论和递推知识。

代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define P 1000000009
#define N 1000000
#define ll long long
using namespace std;
int t;
ll cat[N];
void gcd(ll a,ll b,ll &d,ll &x,ll &y)
{
if (b==){
d=;x=;y=;
}
else {
gcd(b,a%b,d,y,x);y-=x*(a/b);
}
}
ll inv(ll q,ll w)
{
ll d,x,y;
gcd(q,w,d,x,y);
return d==?(x+w)%w:-;
}
void pre()
{
cat[]=;
for (int i=;i<=N;i++)
cat[i]=cat[i-]*(*i-)%P*inv(i+,P)%P;
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
pre();
cin>>t;
while (t)
{
int n;
scanf("%d",&n);
printf("%I64d\n",cat[n/]);
t--;
}
return ;
}

  

【64测试20161112】【Catalan数】【数论】【扩展欧几里得】【逆】的更多相关文章

  1. interesting Integers(数学暴力||数论扩展欧几里得)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAwwAAAHwCAIAAACE0n9nAAAgAElEQVR4nOydfUBT1f/Hbw9202m0r8

  2. 数论 + 扩展欧几里得 - SGU 106. The equation

    The equation Problem's Link Mean: 给你7个数,a,b,c,x1,x2,y1,y2.求满足a*x+b*y=-c的解x满足x1<=x<=x2,y满足y1< ...

  3. [ZLXOI2015]殉国 数论 扩展欧几里得

    题目大意:已知a,b,c,求满足ax+by=c (x>=0,y>=0)的(x+y)最大值与最小值与解的个数. 直接exgcd,求出x,y分别为最小正整数的解,然后一算就出来啦 #inclu ...

  4. 数论--扩展欧几里得exgcd

    算法思想 我们想求得一组\(x,y\)使得 \(ax+by = \gcd(a,b)\) 根据 \(\gcd(a,b) = \gcd(b,a\bmod b)\) 如果我们现在有\(x',y'\) 使得 ...

  5. 【数论】【扩展欧几里得】Codeforces 710D Two Arithmetic Progressions

    题目链接: http://codeforces.com/problemset/problem/710/D 题目大意: 两个等差数列a1x+b1和a2x+b2,求L到R区间内重叠的点有几个. 0 < ...

  6. JZYZOJ1371 青蛙的约会 扩展欧几里得 GTMD数论

    http://172.20.6.3/Problem_Show.asp?id=1371 题意是两个青蛙朝同一个方向跳 http://www.cnblogs.com/jackge/archive/2013 ...

  7. 【bzoj2242】: [SDOI2011]计算器 数论-快速幂-扩展欧几里得-BSGS

    [bzoj2242]: [SDOI2011]计算器 1.快速幂 2.扩展欧几里得(费马小定理) 3.BSGS /* http://www.cnblogs.com/karl07/ */ #include ...

  8. 【扩展欧几里得】BAPC2014 I Interesting Integers (Codeforces GYM 100526)

    题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ...

  9. [P1082][NOIP2012] 同余方程 (扩展欧几里得/乘法逆元)

    最近想学数论 刚好今天(初赛上午)智推了一个数论题 我屁颠屁颠地去学了乘法逆元 然后水掉了P3811 和 P2613 (zcy吊打集训队!)(逃 然后才开始做这题. 乘法逆元 乘法逆元的思路大致就是a ...

随机推荐

  1. JS数组定义【收藏】

    最近在学习JS,刚好学到数组,发现章节还蛮多了而且发现了数组的以前好多不知道的东西,顺便整理下: 数组一共有有四种定义的方式 使用构造函数: var a = new Array(); var b = ...

  2. 关于学习Knockoutjs--入门(一)

    前段时间做项目一直在用knockout,虽然用着不怎么利索,但是知识是一点一点探索的. 首先介绍一下 Knockout是什么? 他是一个很优秀的js库,他最大的功能就是实现双向绑定,它可以帮助你仅使用 ...

  3. checkbox的单选全选,反选,计算价格,删除

    activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...

  4. lua table 排序--满足多条件排序

    前提 假设 一个小怪 有三种属性,等级(level).品质(quality).id(pid) 我们需要对他们进行排序,两种排序情况,第一是单一属性排序,比如按照等级进行排序,或者多种属性进行优先级排序 ...

  5. 关于cookie的文章(cookie与session机制)

    会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...

  6. 剑指offer二:替换空格

    题目描述: 请实现一个函数,将一个字符串中的空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 解题思路: ...

  7. 16s及宏基因组测序公司资源--20161104

    锐羿基因: http://www.realbio.cn/index.php?c=list&cs=keyandongtai& 科研动态更新及时 青岛过程能源所: http://www.c ...

  8. Google Protocol Buffer的安装与.proto文件的定义

    什么是protocol Buffer呢? Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准. 我理解的就是:它是一种轻便高效的结构 ...

  9. 整合Spring Data JPA与Spring MVC: 分页和排序

    之前我们学习了如何使用Jpa访问关系型数据库.比较完整Spring MVC和JPA教程请见Spring Data JPA实战入门,Spring MVC实战入门. 通过Jpa大大简化了我们对数据库的开发 ...

  10. contiki-进程

    进程的结构 Contiki的进程由两部分组成:进程控制块和进程线程.进程控制块存储在内存中,它包含进程运行时的信息,比如:进程名.进程状态.指向进程线程的指针. 进程线程是存储在ROM中的一个代码块. ...