ABC127E
問題
atcoder.jp マスに 配置する 個の駒の間のマンハッタン距離の総和を,とりうる配置のパターンでさらに総和する問題です。
解説
公式解説を読んでも理解に苦しめられたので,少しだけ噛み砕いて記事にします。
そしてなんと,今回からMarkdown記法で書くことにしました。ほとんど更新してなくてすみません。
2点 間のマンハッタン距離を場合の数だけ掛け合わせると良いです。 これについて,具体例をもとに3つのSTEPに分けて理解していきたいと思います。
具体例 で考える
のマスに3個の点を配置する場合を考えます。
STEP 1
点の配置の仕方は図のようになります。点を区別するために番号を振っています。
各配置におけるマンハッタン距離の総和を4通りの場合で総和をとると答えになります。
STEP 2
すべての配置を列挙するのは難しいので,2点間の距離のみに着目して,それが答えに何回足されるかを考えます。
残りの点の配置の仕方は,残りの2マスの中から1マスを選ぶので 通りです。一般化すると,
通りになります。 の制約では,
で算出しても間に合います。
PQの選び方を列挙したら,それぞれのマンハッタン距離を算出し,場合の数をかけて合算します。
ここで, のグリッドから2点を選ぶ場合の数は であり,これを全探索してしまうと計算量は になります。 もし,pythonで書くならば,
for i in range(N*M-1): for j in range(i+1, N*M): ...
のようになると思います。これでは間に合いません。 そこで次の考え方に移ります。
STEP 3
マンハッタン距離の計算において,, は独立しているので,今回は分離して考えます。
x座標の差を,y座標の差を で表しています。
のときは, に何をかけても0なので,考慮する必要はありません。
の選び方とき,2点PQの選び方は 次の3つの自由度から定められるので, 通りになります。
この計算は,ループ処理で1からN-1まで距離を求めればよいので,計算量 で求まります。
- 1つ目の点の 座標を 1 から の中からどれにするか
行の選び方(クリックすると展開されます)
ここの"行の選び方"は, のうち, となる の選び方です。
例えば, のうち,差が 1 となる選び方は, の2通りとなります。 - 1つ目の点の 座標を 1から の中からどれにするか
- 2つ目の点の 座標を 1から の中からどれにするか
y座標についても,x座標と同様に計算ができます。 最後に,STEP 2 で求めた残りの点の場合の数を考慮して,の寄与との寄与の総和を求めると答えになります。
コード
def main(): MOD = 1_000_000_007 N, M, K = map(int, input().split()) ans= 0 # axis: x for d in range(1, N): ans += d * (N-d)*M**2 ans %= MOD # axis: y for d in range(1, M): ans += d * (M-d)*N**2 ans %= MOD nCr = MODnCr(mod=MOD) ans *= nCr(N*M-2, K-2) ans %= MOD print(ans) return