Official

C - Min Max Pair Editorial by KoD


問題文で与えられた条件は、次のどちらかが成り立つことと同値です。

  • \(a_i = i\) かつ \(a_j = j\)
  • \(a_i = j\) かつ \(a_j = i\)

前者が成り立つような組の総数は、\(a_k = k\) であるような \(k\) の個数を \(n\) として \(\frac{n(n - 1)}{2}\) です。

後者については、\(a_i = j\) より \(i\) を固定すると \(j\)\(1\) 通りに定まるので、\(a_i \neq i\) であるような \(i\) を全て試すことで総数を求めることができます。

以上により、時間計算量 \(O (N)\) でこの問題を解くことができました。

実装例 (C++)

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> a(n);
    int same = 0;
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
        a[i] -= 1;
        if (a[i] == i) {
            same += 1;
        }
    }
    long long ans = (long long)same * (same - 1) / 2;
    for (int i = 0; i < n; ++i) {
        if (a[i] > i and a[a[i]] == i) {
            ans += 1;
        }
    }
    cout << ans << '\n';
    return 0;
}

実装例 (Python)

n = int(input())
a = list(map(int, input().split()))

for i in range(n):
  a[i] -= 1

same = 0
for (i, x) in enumerate(a):
  if i == x:
    same += 1

ans = same * (same - 1) // 2
for (i, j) in enumerate(a):
  if i < j and a[j] == i:
    ans += 1

print(ans)

posted:
last update: