• 洛谷P2606 [ZJOI2010]排列计数 组合数学+DP


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

    解法:我们仔细观察这个pi>=pi/2,想到什么了?像不像二叉树中每个点i和它的两个儿子的编号2i和2i+1。

    那么我们可以想象每个点i想它的两个儿子2i/2i+1连边,加上Pi>Pi/2这个条件,那么这棵二叉树就是一棵小根堆。那么我们考虑用dp解决这道题,

    设dp[i]表示i个不同的数组成一棵大小为i的小根堆的方案数,状态转移方程为dp[i]=C(i-1,l[i]) * dp[l[i]] * dp[r[i]] ;解释一下:这里的l[i]/r[i]代表大小为i的完全二叉树(为什么要是完全的?因为题目要求的序号是连续的)的左/右子树大小。这个方程的意思是从i-1个数里面选择l[i]个数作为左子树方案数乘以剩下r[i]个数作为右子树方案数。

    那么我们预处理l[i]/r[i]就可以计算答案了。

    注意此题p有可能>=n,所以要用Lucas定理计算组合数。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL; 
     4 const int N=1e6+10;
     5 int n,P,l[N],r[N],dp[N];
     6 
     7 int power(int x,int p) {
     8     int ret=1;
     9     for (;p;p>>=1) {
    10         if (p&1) ret=(LL)ret*x%P;
    11         x=(LL)x*x%P;
    12     }
    13     return ret;
    14 }
    15 
    16 int fac[N],inv[N];
    17 void prework(int n) {
    18     fac[0]=1; inv[0]=1;
    19     for (int i=1;i<=n;i++) {
    20         fac[i]=(LL)i*fac[i-1]%P;
    21         inv[i]=power(fac[i],P-2);
    22     }
    23     l[1]=0;
    24     for(int i=2,g=1;i<=n;g<<=1,i+=g) {
    25         for(int j=1;j<=g;j++) l[i+j-1]=l[i+j-2]+1;
    26         for(int j=1;j<=g;j++) l[i+g+j-1]=l[i+g+j-2];
    27     }
    28     for (int i=1;i<=n;i++) r[i]=i-1-l[i];
    29 }
    30 
    31 int C(int n,int m) {
    32     if (n>=P || m>=P) return (LL)C(n/P,m/P)*C(n%P,m%P)%P;
    33     else return (LL)fac[n]*inv[m]%P*inv[n-m]%P;
    34 }
    35 
    36 int main()
    37 {
    38     cin>>n>>P;
    39     prework(n);
    40     dp[0]=dp[1]=1;
    41     for (int i=2;i<=n;i++)
    42         dp[i]=(LL)C(i-1,l[i])*dp[l[i]]%P*dp[r[i]]%P;
    43     cout<<dp[n]<<endl;    
    44     return 0;
    45 }
  • 相关阅读:
    jQuery 选择器:元素选择器、#id 选择器、.class 选择器
    jQuery 语法:文档就绪事件
    jQuery 安装:多种方法在网页中添加 jQuery
    jQuery 简介:什么事jQuery?为什么要学jQuery?
    SQL 快速参考:SQL语句语法
    SQL FORMAT() 函数:对字段的显示进行格式化
    Mybatis-Plus逻辑删除
    Mybatis-Plus中的ActiveRecord
    Mybatis-Plus使用Oracle的序列
    SpringBoot整合Mybatis-Plus
  • 原文地址:https://www.cnblogs.com/clno1/p/11656581.html
Copyright © 2020-2023  润新知