【AtCoder】ABC 462 D - Accomplice

D - Accompliceatcoder.jp favicon

実行時間制限: 2 sec / メモリ制限: 1024 MiB / Difficulty: 798 / NoviSteps: 1Q / 配点: 400 点

問題概要

とある館で起きた殺人事件の犯人の候補が NN 人いる。 人 ii は時刻 SiS_i に館に入り、時刻 TiT_i に館を出て、ほかの時刻には出入りしなかった。

犯行について以下のことが分かっている。

  • 犯人はちょうど 22 人いる。
  • 犯行はある整数時刻 xx に開始し、DD 単位時間かけて行われ、時刻 x+Dx + D に完了した。
  • 犯人は 22 人とも犯行開始から犯行完了まで常に館にいた(犯行開始と同時に館に入ったり、犯行完了と同時に館を出たりした可能性もある)。

NN 人の犯人候補の中に犯人が 22 人ともいると仮定したとき、22 人の犯人の組み合わせと犯行開始時刻の組としてありうるものは何通りあるか求めよ。

制約

  • 2N2×1052 \leq N \leq 2 \times 10^5
  • 1SiTi1061 \leq S_i \leq T_i \leq 10^6
  • 1D1061 \leq D \leq 10^6
  • 入力される値は全て整数

考察

まず、各時刻 tt に何人が犯行可能かを考える。

ii が時刻 tt に犯行可能である条件は、

Sitt+DTi    SitTiDS_i \leq t \land t + D \leq T_i \iff S_i \leq t \leq T_i - D

である。

したがって、人 ii が犯行可能な時刻の候補となる区間は [Si,TiD][S_i, T_i - D] である。


また、ある時刻 tt に犯行可能な人の数を ctc_t とすると、ctc_t 人の中から犯人を 22 人選ぶ方法は ct(ct1)2\frac{c_t(c_t - 1)}{2} 通りあるので、求める答えは

tct(ct1)2\sum_{t} \frac{c_t(c_t - 1)}{2}

となる。


今回は時刻の上限が 10610^6 なので、長さ 10610^6 の配列を用意して、imos法の要領で ctc_t を求めることができる。

実装例

CPP
1.#include <bits/stdc++.h>
2.using namespace std;
3.
4.#define rep(i, start, end) for (auto i = (start); (i) < (end); (i)++)
5.
6.using ll = long long;
7.
8.// ======================================== //
9.
10.int main()
11.{
12. int N, D;
13. cin >> N >> D;
14.
15. vector<int> time(1001000, 0);
16. rep(i, 0, N) {
17. int S, T;
18. cin >> S >> T;
19.
20. if (S <= T - D) {
21. time[S]++;
22. time[T - D + 1]--;
23. }
24. }
25.
26. ll ans = 0, cnt = 0;
27. rep(t, 1, 1001000) {
28. cnt += time[t];
29. ans += cnt * (cnt - 1) / 2;
30. }
31.
32. cout << ans << endl;
33.
34. return 0;
35.}
atcoder.jp favicon

実装時間: 15 分

コメント

AtCoderの世界でも殺人事件って起こるのか...