zoukankan      html  css  js  c++  java
  • 洛谷 P4370 [Code+#4]组合数问题2

    Description

    洛谷传送门

    Solution

    P4369 [Code+#4]组合数问题这道题的加强版……好吧,两道题并没有什么关系。

    考虑到 (C_n^m > C_{n - 1}^m),所以我们先把 (C_n^1) 放到一个大根堆中,然后每次取出最大的 (C_x^y),把 (C_{x - 1}^y) 放到堆中。

    这样重复 (k) 遍,累加答案即可。

    但是,组合数过大,取模之后就没有大小关系了,那该怎么办呢?

    其实也很简单,取对数就好了。

    这就要用到一些高中数学知识了:

    (log_2frac{n!}{m!(n-m)!}=log_2n!-log_2m!-log_2(n-m)!=sum_{i=1}^nlog_2i-sum_{i=1}^mlog_2i-sum_{i=1}^{n-m}log_2i)

    所以我们求出前缀积乘法逆元(也要前缀积),(log)(前缀和)即可。

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <cmath>
    #define ll long long
    
    using namespace std;
    
    const ll mod = 1e9 + 7;
    const ll N = 1e6 + 10;
    ll n, k, ans;
    struct node{
    	ll x, y;
    	double val;
    	bool operator < (const node &b) const{
    		return val < b.val;
    	}
    };
    priority_queue<node> q;
    ll fac[N], inv[N];
    double lg[N];
    
    inline void prework(){
    	inv[0] = inv[1] = fac[0] = fac[1] = 1;
    	lg[1] = log(1);
    	for(ll i = 2; i <= N - 10; i++){
    		inv[i] = (mod - mod / i) * inv[mod % i] % mod;
    		fac[i] = fac[i - 1] * i % mod;
    		lg[i] = lg[i - 1] + log(i);
    	}
    	for(ll i = 1; i <= N - 10; i++)
    		inv[i] = (inv[i - 1] * inv[i]) % mod;
    }
    
    signed main(){
    	prework();
    	scanf("%lld%lld", &n, &k);
    	for(ll i = 0; i <= n; i++)
    		q.push((node){n, i, lg[n] - lg[i] - lg[n - i]});;
    	for(ll i = 1; i <= k; i++){
    		node now = q.top();
    		q.pop();
    		ans = (ans + fac[now.x] * inv[now.y] % mod * inv[now.x - now.y] % mod) % mod;
    		q.push((node){now.x - 1, now.y, lg[now.x - 1] - lg[now.y] - lg[now.x - 1 - now.y]});
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    End

    本文来自博客园,作者:xixike,转载请注明原文链接:https://www.cnblogs.com/xixike/p/15375471.html

  • 相关阅读:
    iOS开发之Masonry框架源码解析
    iOS开发针对对Masonry下的FPS优化讨论
    React-native Android环境搭建
    Android中ListView使用总结
    Android开发布局方式
    轮播图
    大文件断点下载
    基于第三方库FMDB的数据库的二次封装
    md5加密
    AssignToObject文件(字典转模型、字典数组转模型数组)
  • 原文地址:https://www.cnblogs.com/xixike/p/15375471.html
Copyright © 2011-2022 走看看