zoukankan      html  css  js  c++  java
  • 洛谷P2606 [ZJOI2010]排列计数

    题目描述

    称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大,只能输出模P以后的值

    输入输出格式

    输入格式:

     

    输入文件的第一行包含两个整数 n和p,含义如上所述。

     

    输出格式:

     

    输出文件中仅包含一个整数,表示计算1,2,⋯, ���的排列中, Magic排列的个数模 p的值。

     

    输入输出样例

    输入样例#1:
    20 23 
    输出样例#1:
    16
    

    说明

    100%的数据中,1 ≤N ≤ 10^6, P≤ 10^9,p是一个质数。

    题目大意:求1--n能构成小根堆的排列

    题解:

    暴力30...

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,p,ans,a[1000009];
    int main(){
        scanf("%d%d",&n,&p);
        for(int i=1;i<=n;i++)a[i]=i;
        do{
            bool flag=false;
            for(register int i=2;i<=n;i++){
                if(a[i]<a[i/2]){
                    flag=true;break;
                }
            }
            if(!flag)ans=(ans%p+1%p)%p;
        }while(next_permutation(a+1,a+n+1));
        printf("%d
    ",ans);
        return 0;
    }

    正解:Lucas定理+树形dp

    没看出来是小根堆...我这个沙茶...

    然后根一定是最小的,然后f[i]=c(s[i]-1,s[i<<1])*f[l]*f[r]

    f[i]表示以i为根的小根堆的数量....然后左子树的大小就是从s[i]-1(减去根

    中选出s[i<<1],用Lucas定理求就行啦...

    因为有子问题的....

    ps:不知道为什么一直WA,抱着试试看的心态,我多加了一个取模。

    你猜怎么着?就A了....

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 1000009
    #define LL long long
    using namespace std;
    
    LL n,p;
    LL f[maxn],inv[maxn],s[2*maxn],dp[maxn];
    
    LL ksm(LL x,LL y){
        LL ret=1%y;
        while(y){
            if(y&1)ret=(1LL*ret*x)%p;
            x=1LL*x*x%p;
            y>>=1;
        }
        return ret;
    }
    
    void pre(){
        f[0]=inv[0]=1;
        for(int i=1;i<=n;i++)f[i]=(1LL*f[i-1]*i)%p;
        for(int i=1;i<=n;i++)inv[i]=ksm(f[i],p-2)%p;
    }
    
    LL C(LL n,LL m){
        return 1LL*f[n]*inv[m]%p*inv[n-m]%p;
    }
     
    LL Lucas(LL n,LL m){
        if(!m)return 1;
        return C(n%p,m%p)*Lucas(n/p,m/p)%p;
    }
    
    int main(){
        scanf("%lld%lld",&n,&p);
        pre();
        for(int i=n;i>=1;i--){
            s[i]=s[i<<1]+s[i<<1|1]+1;
            dp[i]=Lucas(s[i]-1,s[i<<1])%p;
            if((i<<1)<=n)dp[i]=dp[i]*dp[i<<1]%p;
            if((i<<1|1)<=n)dp[i]=dp[i]*dp[i<<1|1]%p;
            dp[i]=dp[i]%p;
        }
        printf("%lld
    ",dp[1]%p);
        return 0;
    }
  • 相关阅读:
    SpringMVC异常处理
    SpringMVC参数绑定、Post乱码解决方法
    @RequestMapping与controller方法返回值介绍
    Git学习总结(标签管理)
    Git分支管理
    远程仓库
    可用来修改bean对象的BeanPostProcessor
    @Configuration的使用
    Spring配置:用context:property-placeholder替换PropertyPlaceholderConfigurer
    深入剖析 Spring 框架的 BeanFactory
  • 原文地址:https://www.cnblogs.com/zzyh/p/7661447.html
Copyright © 2011-2022 走看看