• [CF961G] Partitions


    [题目链接]

    https://codeforces.com/contest/961/problem/G

    [题解]

    首先每个物品是独立的 , 考虑其贡献 , 为 :

    (iegin{Bmatrix}k - 1\n - iend{Bmatrix}{n - 1 choose i - 1})

    考虑暴力拆解斯特林数 , 化简得贡献

    (sum{frac{(-1)^{j}}{(j!)(k - j - 1)!}} cdot ((k - j) ^ {n - 1} + (n - 1)(k - j) ^ {n - 2}))

    时间复杂度 : (O(NlogN)) (瓶颈在快速幂)

    [代码]

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i , l , r) for (int i = (l); i < (r); ++i)
    
    typedef long long LL;
    
    const int MN = 3e5 + 5 , mod = 1e9 + 7;
    
    int N , K , sum , ans , fac[MN] , ifac[MN];
    
    inline void inc(int &x , int y) {
    		x = x + y < mod ? x + y : x + y - mod;
    }
    inline void dec(int &x , int y) {
    		x = x - y >= 0 ? x - y : x - y + mod;
    }
    inline int qPow(int a , int b) {
    		if (b < 0) return 1;
    		int c = 1;
    		for (; b; b >>= 1 , a = 1ll * a * a % mod) if (b & 1) c = 1ll * c * a % mod;
    		return c;
    }
    
    int main() {
    		
    		scanf("%d%d" , &N , &K);
    		for (int i = 1; i <= N; ++i) {
    				int x; scanf("%d" , &x);
    				inc(sum , x);
    		}
    		fac[0] = 1;
    		for (int i = 1; i <= N; ++i) fac[i] = 1ll * fac[i - 1] * i % mod;
    		ifac[N] = qPow(fac[N] , mod - 2);
    		for (int i = N - 1; i >= 0; --i) ifac[i] = 1ll * ifac[i + 1] * (i + 1) % mod;
    		for (int j = 0; j < K; ++j) {
    				int val = 1ll * ((j & 1) ? mod - 1 : 1) * ifac[j] % mod * ifac[K - 1 - j] % mod;
    				inc(ans , 1ll * val * qPow(K - j , N - 2) % mod * (K - j + N - 1) % mod);
    		}
    		printf("%d
    " , 1ll * sum * ans % mod);
    	  return 0;
    }
  • 相关阅读:
    HDU 5546 深搜吧 主要是提取的时候容易重复
    HDU 5543 新型01背包 两端放一半就可以有其价值
    HDU 2586 查找两点之间的距离
    HDU 5652 二分加搜索 http://acm.split.hdu.edu.cn/showproblem.php?pid=5652
    美句
    最短路径问题
    1766 装果子
    Watchcow
    codevs 4768 跳石头
    noi 7219:复杂的整数划分问题
  • 原文地址:https://www.cnblogs.com/evenbao/p/14321643.html
Copyright © 2020-2023  润新知