zoukankan      html  css  js  c++  java
  • [CP1804]组合数问题2

    题目大意:
      给定两个数$n(nle10^6)$和$k(kle10^5)$,找到$k$个不同的满足$0le ble ale n$的组合数$inom a b$,求这$k$个组合数的最大值。

    思路:
      显然对于同一个$a$,$b=lfloorfrac a 2 floor$时组合数取到最大值,可以先对于所有的$0le ale n$求出$b=lfloorfrac a 2 floor$时的组合数的值,用一个堆来维护。取走这个数同时把$a$相同的,仅次于它的组合数加入堆,比较时为避免精度问题用对数比较。时间复杂度$O(nlog n)$。

     1 #include<queue>
     2 #include<cmath>
     3 #include<cstdio>
     4 #include<cctype>
     5 typedef long long int64;
     6 inline int getint() {
     7     register char ch;
     8     while(!isdigit(ch=getchar()));
     9     register int x=ch^'0';
    10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    11     return x;
    12 }
    13 const int N=1e6+1,mod=1e9+7;
    14 int fact[N],factinv[N];
    15 void exgcd(const int &a,const int &b,int &x,int &y) {
    16     if(!b) {
    17         x=1,y=0;
    18         return;
    19     }
    20     exgcd(b,a%b,y,x);
    21     y-=a/b*x;
    22 }
    23 inline int inv(const int &x) {
    24     int ret,tmp;
    25     exgcd(x,mod,ret,tmp);
    26     return (ret%mod+mod)%mod;
    27 }
    28 inline int calc(const int &a,const int &b) {
    29     return (int64)fact[a]*factinv[b]%mod*factinv[a-b]%mod;
    30 }
    31 struct Node {
    32     long double val;
    33     int a,b,d;
    34     bool operator < (const Node &another) const {
    35         return val<another.val;
    36     }
    37 };
    38 std::priority_queue<Node> q;
    39 int main() {
    40     const int n=getint(),k=getint();
    41     for(register int i=fact[0]=1;i<=n;i++) {
    42         fact[i]=(int64)fact[i-1]*i%mod;
    43     }
    44     factinv[n]=inv(fact[n]);
    45     for(register int i=n;i;i--) {
    46         factinv[i-1]=(int64)factinv[i]*i%mod;
    47     }
    48     for(register int a=0;a<=n;a++) {
    49         if(a&1) {
    50             q.push((Node){lgamma(a+1)-lgamma(a/2+1)-lgamma(a-a/2+1),a,a/2,-1});
    51             q.push((Node){lgamma(a+1)-lgamma(a/2+2)-lgamma(a-a/2),a,a/2+1,1});
    52         } else {
    53             q.push((Node){lgamma(a+1)-lgamma(a/2+1)-lgamma(a-a/2+1),a,a/2,0});
    54         }
    55     }
    56     int ans=0;
    57     for(register int cnt=0;cnt<k;cnt++) {
    58         int a=q.top().a,b=q.top().b,d=q.top().d;q.pop();
    59         (ans+=calc(a,b))%=mod;
    60         if(d!=1&&b!=1) q.push((Node){lgamma(a+1)-lgamma(b)-lgamma(a-b+2),a,b-1,-1});
    61         if(d!=-1&&b!=a) q.push((Node){lgamma(a+1)-lgamma(b+2)-lgamma(a-b),a,b+1,1});
    62     }
    63     printf("%d
    ",ans);
    64     return 0;
    65 } 
  • 相关阅读:
    PAT甲题题解-1030. Travel Plan (30)-最短路+输出路径
    PAT甲题题解-1029. Median (25)-求两序列的中位数,题目更新了之后不水了
    PAT甲题题解-1028. List Sorting (25)-水排序
    BZOJ 1492 货币兑换Cash
    Codeforces 276D Little Girl and Maximum XOR
    Codeforces 526E Transmitting Levels
    Codeforces 335B Palindrome
    BZOJ 2527 Meteors
    Codeforces 449D Jzzhu and Numbers
    FJ省队集训DAY4 T3
  • 原文地址:https://www.cnblogs.com/skylee03/p/8697107.html
Copyright © 2011-2022 走看看