[ABC127E] Cell Distance

  • 原题链接
  • 题意:给出 \(n \times m\) 的矩阵,都小于 \(2e5\) ,求从 \(n \times m\) 个矩阵中拿出 \(k <= n \times m\) 个点,在所有方案中,求每个方案中,每个点距离其他点的曼哈顿距离之和,然后求所有方案的各个距离之和的总和。
  • 题解:枚举横着两个点的距离为 \(1 <= lenx <= n\) 然后,其贡献为 \(lenx \times ( n - lenx)\times m^2\),然后对答案的贡献值就是显然从所有中选出 \(k-2\) 个的方案数乘贡献,即 $$\sum_{lenx = 1}^{n} (nm-2, k-2) \times lenx \times ( n - lenx)\times m^2$$
    所以同理,这只是算了一半的答案,另一半则是 $$\sum_{leny = 1}^{n} (nm-2, k-2) \times leny \times ( m - leny )\times n^2$$
  • 代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 200009;
typedef long long ll;
const ll mod = 1000000007;
ll fac[N];
ll q_mi(ll a, ll k, ll mod) {
    ll ret = 1;
    ll x = a;
    while (k) {
        if (k & 1) (ret *= x) %= mod;
        (x *= x) %= mod;
        k >>= 1;
    }
    return ret;
}
ll inv(ll a) { return (q_mi(a, mod - 2, mod) % mod + mod) % mod; }
ll C(ll n, ll m) {return fac[n] * (inv(fac[m])) % mod * inv(fac[n-m]) % mod;}
void init() {
    fac[0] = 1;
    for (int i = 1; i < N; i++) {
        (fac[i] = fac[i-1] * i) %= mod;
    }
}


void solve() {
    ll n, m, k;cin >> n >> m >> k;
    ll ans = 0;
    for (ll i = 1; i <= n; i++) {
        (ans += C(n*m-2, k-2) * (n - i) % mod * m % mod * m % mod  * i%mod) %= mod;
    }
    for (ll i = 1; i <= m; i++) {
         (ans += C(n*m-2, k-2) * (m - i) % mod * n % mod * n % mod  * i%mod) %= mod;
    }
    cout << ans << endl;
}
signed main() {
    ios::sync_with_stdio(0);
    init();
    ll t = 1;//cin >> t;
    while (t--)solve();
    return 0;
}

posted @ 2021-03-17 20:12  u_yan  阅读(113)  评论(0编辑  收藏  举报