码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 2111 Perm 排列计数(满二叉树)

时间:2014-06-23 06:23:33      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:style   class   blog   http   get      

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2111

题意:求1到n有多少种排列满足:A[i]>A[i/2](2<=i<=n)。

思路:形式类似二叉树。建模之后其实就是n个节点的不同的满二叉树有多少种?用f[i]表示i个节点的满二叉树个数,则f[n]=f[L]*f[R]*C(n-1,L)。其中L和R对于确定的n来说是确定的。比如n=10时,左右子树分别有6、3个点。

 

i64 a[N],n,p,f[N];


void init()
{
    int i;
    a[0]=1;
    FOR1(i,N-1) a[i]=a[i-1]*i%p;
}


i64 exGcd(i64 a,i64 b,i64 &x,i64 &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    i64 temp=exGcd(b,a%b,x,y);
    i64 t=x;
    x=y;
    y=t-a/b*y;
    return temp;
}


i64 reverse(i64 a)
{
    i64 x,y;
    exGcd(a,p,x,y);
    x=(x%p+p)%p;
    return x;
}


i64 C(i64 n,i64 m)
{
    return a[n]*reverse(a[m]*a[n-m]%p)%p;
}




int get(int x)
{
    if(x==1) return 1;
    int i;
    for(i=1;;i++)
    {
        x-=(1<<i);
        if(x<=(1<<(i+1)))
        {
            return (1<<i)-1+max(0,x-(1<<i));
        }
    }
}


int main()
{
    RD(n,p); init();
    int i,L,R;
    f[1]=1; f[2]=1;
    for(i=3;i<=n;i++)
    {
        R=get(i-1);
        L=i-1-R;
        f[i]=f[L]*f[R]%p*C(i-1,L)%p;
    }
    PR(f[n]);
}

 

 

 

BZOJ 2111 Perm 排列计数(满二叉树),布布扣,bubuko.com

BZOJ 2111 Perm 排列计数(满二叉树)

标签:style   class   blog   http   get      

原文地址:http://www.cnblogs.com/jianglangcaijin/p/3799680.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!