zoukankan      html  css  js  c++  java
  • CF1513E-Cost Equilibrium

    题目链接
    思路
    所有数之和sum除以n就是所求的平均值。如果(sum mod n eq 0)那么无解,假设(x=sum/n.)那么小于x的值就是汇点,大于x的值就是源点。令小于x的数有cnt1个,大于x的数有cnt2个,那么等于x的数就有(n-cnt1-cnt2)个。因为等于x的数无影响,所以可以随便放,那么就是在n个位置中找x个位置的方案数,即是(cnt = C_{n}^{n-cnt1-cnt2})
    接下来考虑源点和汇点的情况:
    若源点个数 (leq0) 或者 汇点个数 (leq 0) ,那么任意的排列方式都是可以的。所以只需要计算一下他们的多重全排列方案数就行了。最后答案再乘上等于x的数的方案数即可。
    (多重全排列:假设有n个不同的数,现在有(k_1)(a_1)(k_2)(a_2)(k_3)(a_3),那么其多重全排列数就是(frac{(k_1+k_2+k_3)!}{k_1!*k_2!*k_3!}),意思就是对于原数组先进行全排列,然后对于相同的数字自己有(k_i!)种内部相同的全排列数,除去就行)
    若源点个数 (> 1) 并且 汇点个数 (>1),那么就必须要让汇点的所有点在一侧,源点的所有点在一侧,两类点不能交错放在一起。例如1212或者1221这种,因为当前源点既可以选择进的汇点,也可以选择远的汇点。那就分别考虑一侧全部是源点的多重全排列数,另一侧全部是汇点的多重全排列数,最后答案乘上等于x的方案数就行了。
    具体可以看代码更为清楚。
    代码

    /*人一我百,人十我万*/
    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    typedef pair<int, LL> PIL;
    typedef pair<int, int> PII;
    typedef unsigned long long ULL;
    #define x first
    #define y second
    const int N = 1e5 + 10, M = 1e5 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    #define gcd __gcd
    
    int a[N], b[N], c[N];
    map<int, int> cnt;
    LL f[N], inv[N];
    
    LL kpow(LL a, LL n) {
        LL res = 1;
        while(n) {
            if(n & 1) res = res * a % mod;
            n >>= 1;
            a = a * a % mod;
        }
        return res;
    }
    
    LL C(LL n, LL m) {
        if(m > n) return 0;
        return f[n] * inv[m] % mod * inv[n - m] % mod;
    }
    
    void init(int n) {
        f[0] = 1;
        inv[0] = 1;
        for(int i = 1; i <= n; i++) {
            f[i] = f[i - 1] * i % mod;
            inv[i] = inv[i - 1] * kpow(i, mod - 2) % mod;
        }
    }
    
    void solve() {
        int n;
        scanf("%d", &n);
        LL sum = 0;
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            cnt[a[i]]++;
            sum += a[i];
        }
        if(sum % n != 0) {
            puts("0");
            return;
        }
        int idx1 = 0, idx2 = 0;
        int x = sum / n;
        for(int i = 1; i <= n; i++) {
            if(a[i] < x) b[++idx1] = a[i];
            else if(a[i] > x) c[++idx2] = a[i];
        }
        sort(b + 1, b + 1 + idx1);
        sort(c + 1, c + 1 + idx2);
        int len1 = unique(b + 1, b + 1 + idx1) - b - 1;
        int len2 = unique(c + 1, c + 1 + idx2) - c - 1;
        if(idx1 <= 1 || idx2 <= 1) {
            LL res = C(n, n - idx1 - idx2) * f[idx1 + idx2] % mod;
            if(idx1) {
                for(int i = 1; i <= len1; i++) {
                    res = res * inv[cnt[b[i]]] % mod;
                }
            }
            if(idx2) {
                for(int i = 1; i <= len2; i++) {
                    res = res * inv[cnt[c[i]]] % mod;
                }
            }
            printf("%lld
    ", res);
            return;
        }
    
        LL res = C(n, n - idx1 - idx2) * f[idx1] % mod * f[idx2] % mod;
        if(idx1) {
            for(int i = 1; i <= len1; i++) {
                res = res * inv[cnt[b[i]]] % mod;
            }
        }
        if(idx2) {
            for(int i = 1; i <= len2; i++) {
                res = res * inv[cnt[c[i]]] % mod;
            }
        }
        printf("%lld
    ", res * 2 % mod);
    }
    
    int main() {
        #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        #endif // ONLINE_JUDGE
        // std::ios::sync_with_stdio(false); 
        // cin.tie(0); cout.tie(0);
    
        // int t; cin >> t; while(t--)
        init(1e5);
        solve();
        return 0;
    }
    
  • 相关阅读:
    windows的80端口被占用时的处理方法
    Ansible自动化运维工具安装与使用实例
    Tomcat的测试网页换成自己项目首页
    LeetCode 219. Contains Duplicate II
    LeetCode Contest 177
    LeetCode 217. Contains Duplicate
    LeetCode 216. Combination Sum III(DFS)
    LeetCode 215. Kth Largest Element in an Array(排序)
    Contest 176 LeetCode 1354. Construct Target Array With Multiple Sums(优先队列,递推)
    Contest 176
  • 原文地址:https://www.cnblogs.com/ZX-GO/p/14975836.html
Copyright © 2011-2022 走看看