zoukankan      html  css  js  c++  java
  • AtCoder ABC 127E Cell Distance

    题目链接:https://atcoder.jp/contests/abc127/tasks/abc127_e

    题目大意

      给定一个$N*M$的棋盘,二元组$(x, y),1 leq x leq N,1 leq y leq M$,表示棋盘上的某一个位置,现在要在棋盘上选 K 个不同的位置,记为$(x_1, y_1), (x_2, y_2), dots, (x_K, y_K)$,选择的相应代价为$sum_{i=1}^{K-1} sum_{j=i+1}^K (|x_i - x_j| + |y_i - y_j|)$,输出所有可能方案的代价总和。

    分析

      首先不难发现,x 和 y 是可以分开计算的,所以只需要求$sum_{i=1}^{K-1} sum_{j=i+1}^K |x_i - x_j|$即可,同理可计算$sum_{i=1}^{K-1} sum_{j=i+1}^K |y_i - y_j|$。
      假如我们固定棋盘上 2 个位置$x_{i_1, j_1}, x_{i_2, j_2}$不动,在这种情况下,有$ binom{N*M-2}{K-2}$种选择方案,换句话说就是$|x_{i_1, j_1} - x_{i_2, j_2}|$出现了$ binom{N*M-2}{K-2}$次。
      但枚举所有点对无疑是要超时的,为此我们可以枚举$d = |x_{i_1, j_1} - x_{i_2, j_2}|$,$d in [1, K - 1]$。
      可以先找找规律,当 d == 1 时,看看有多少对$(x_{i_1, j_1}, x_{i_2, j_2})$是满足的。
      可以发现,只要两个点纵坐标差值为1,就都满足。
      于是当 d == 1 时,有$M^2 * (N - 1)$种$(x_{i_1, j_1}, x_{i_2, j_2})$满足$d == |x_{i_1, j_1} - x_{i_2, j_2}|$。
      以此类推,可以找出规律:对于每个 d,都有$d * M^2 * (N - d)$种$(x_{i_1, j_1}, x_{i_2, j_2})$满足$d == |x_{i_1, j_1} - x_{i_2, j_2}|$。
      那么对于每个 d,它对答案的贡献就为$ binom{N*M-2}{K-2} * d * M^2 * (N - d)$。
      把所有的累加起来即可。

    代码如下

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3  
      4 #define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
      5 #define Rep(i,n) for (int i = 0; i < (n); ++i)
      6 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
      7 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
      8 #define ForLL(i, s, t) for (LL i = LL(s); i <= LL(t); ++i)
      9 #define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i)
     10 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
     11 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
     12  
     13 #define pr(x) cout << #x << " = " << x << "  "
     14 #define prln(x) cout << #x << " = " << x << endl
     15  
     16 #define LOWBIT(x) ((x)&(-x))
     17  
     18 #define ALL(x) x.begin(),x.end()
     19 #define INS(x) inserter(x,x.begin())
     20  
     21 #define ms0(a) memset(a,0,sizeof(a))
     22 #define msI(a) memset(a,inf,sizeof(a))
     23 #define msM(a) memset(a,-1,sizeof(a))
     24 
     25 #define MP make_pair
     26 #define PB push_back
     27 #define ft first
     28 #define sd second
     29  
     30 template<typename T1, typename T2>
     31 istream &operator>>(istream &in, pair<T1, T2> &p) {
     32     in >> p.first >> p.second;
     33     return in;
     34 }
     35  
     36 template<typename T>
     37 istream &operator>>(istream &in, vector<T> &v) {
     38     for (auto &x: v)
     39         in >> x;
     40     return in;
     41 }
     42  
     43 template<typename T1, typename T2>
     44 ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
     45     out << "[" << p.first << ", " << p.second << "]" << "
    ";
     46     return out;
     47 }
     48 
     49 inline int gc(){
     50     static const int BUF = 1e7;
     51     static char buf[BUF], *bg = buf + BUF, *ed = bg;
     52     
     53     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
     54     return *bg++;
     55 } 
     56 
     57 inline int ri(){
     58     int x = 0, f = 1, c = gc();
     59     for(; c<48||c>57; f = c=='-'?-1:f, c=gc());
     60     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
     61     return x*f;
     62 }
     63  
     64 typedef long long LL;
     65 typedef unsigned long long uLL;
     66 typedef pair< double, double > PDD;
     67 typedef pair< int, int > PII;
     68 typedef pair< string, int > PSI;
     69 typedef set< int > SI;
     70 typedef vector< int > VI;
     71 typedef vector< PII > VPII;
     72 typedef map< int, int > MII;
     73 typedef pair< LL, LL > PLL;
     74 typedef vector< LL > VL;
     75 typedef vector< VL > VVL;
     76 const double EPS = 1e-10;
     77 const LL inf = 0x7fffffff;
     78 const LL infLL = 0x7fffffffffffffffLL;
     79 const LL mod = 1e9 + 7;
     80 const int maxN = 2e5 + 7;
     81 const LL ONE = 1;
     82 const LL evenBits = 0xaaaaaaaaaaaaaaaa;
     83 const LL oddBits = 0x5555555555555555;
     84 
     85 LL fac[maxN];
     86 void init_fact() {
     87     fac[0] = 1;
     88     For(i, 1, maxN - 1) {
     89         fac[i] = (i * fac[i - 1]) % mod;
     90     }
     91 }
     92 
     93 //ax + by = gcd(a, b) = d
     94 // 扩展欧几里德算法
     95 /**
     96  *    a*x + b*y = 1
     97  *    如果ab互质,有解
     98  *    x就是a关于b的逆元
     99  *    y就是b关于a的逆元
    100  *     
    101  *    证明: 
    102  *        a*x % b + b*y % b = 1 % b
    103  *        a*x % b = 1 % b
    104  *        a*x = 1 (mod b)
    105  */
    106 inline void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){
    107     if (!b) {d = a, x = 1, y = 0;}
    108     else{
    109         ex_gcd(b, a % b, y, x, d);
    110         y -= x * (a / b);
    111     }
    112 }
    113 
    114 // 求a关于p的逆元,如果不存在,返回-1 
    115 // a与p互质,逆元才存在 
    116 inline LL inv_mod(LL a, LL p = mod){
    117     LL d, x, y;
    118     ex_gcd(a, p, x, y, d);
    119     return d == 1 ? (x % p + p) % p : -1;
    120 }
    121 
    122 inline LL comb_mod(LL m, LL n) {
    123     LL ret;
    124     if(m > n) swap(m, n);
    125     ret = (fac[n] * inv_mod(fac[m], mod)) % mod;
    126     ret = (ret * inv_mod(fac[n - m], mod)) % mod;
    127     return ret;
    128 }
    129 
    130 void add_mod(LL &a, LL b) {
    131     a = (a + b) % mod;
    132     if(a < 0) a += mod;
    133 }
    134 
    135 int N, M, K;
    136 LL ans;
    137 
    138 int main(){
    139     INIT(); 
    140     init_fact();
    141     cin >> N >> M >> K;
    142     LL cnt = comb_mod(K - 2, N * M - 2);
    143     
    144     ForLL(d, 1, N - 1) add_mod(ans, cnt * ((d * M * M * (N - d)) % mod));
    145     ForLL(d, 1, M - 1) add_mod(ans, cnt * ((d * N * N * (M - d)) % mod));
    146     cout << ans << endl;
    147     return 0;
    148 }
    View Code
  • 相关阅读:
    USACO Section 1.3 : Mixing Milk
    USACO Section 1.3 : Prime Cryptarithm
    USACO Section 1.2 : Name That Number
    USACO Section 1.3 : Calf Flac
    USACO Section 1.2 : Palindromic Squares
    Global.asax详解
    sql语句字符串处理大全
    ASP.net:URL重写实现IHttpHandler接口
    asp.net中使用基于角色role的Forms验证
    时间Table.TransformColumns(Power Query 之 M 语言)
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/10941594.html
Copyright © 2011-2022 走看看