PROBLEM LINK:
Practice
Contest: Division 1
Contest: Division 2
Contest: Division 3
Contest: Division 4
Author: raysh07
Tester: sushil2006
Editorialist: iceknight1093
DIFFICULTY:
Cakewalk
PREREQUISITES:
Maps/sorting
PROBLEM:
Given an array A, count the number of pairs such that A_i - A_j = i - j
EXPLANATION:
To solve this problem, we rearrange the equation A_i - A_j = i - j a bit to obtain the equation
instead.
So, if we define B_i = A_i - i, we’re now looking for the number of pairs (i, j) such that i \lt j and B_i = B_j.
Counting the number of equal pairs of elements in an array of length N can be done in \mathcal{O}(N\log N) in several ways.
Perhaps the easiest way is to use a map (dictionary in Python.)
Let M be a map, initially empty.
For each i = 1, 2, 3, \ldots, N in order,
- First, add M[B_i] to the answer.
This will count the number of valid pairs whose second index equals i. - Then, add 1 to M[B_i].
This is so that index i will be added for future occurrences of the same value.
In the end, print the answer.
Standard map operations are \mathcal{O}(\log N) in C++, so this is an \mathcal{O}(N\log N) solution which is perfectly fine.
There are other solutions as well: for example you can use sorting and apply this algorithm.
TIME COMPLEXITY:
\mathcal{O}(N\log N) per testcase.
CODE:
Editorialist's code (C++)
// #include <bits/allocator.h>
// #pragma GCC optimize("Ofast,unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#include "bits/stdc++.h"
using namespace std;
using ll = long long int;
mt19937_64 RNG(chrono::high_resolution_clock::now().time_since_epoch().count());
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
int t; cin >> t;
while (t--) {
int n; cin >> n;
vector a(n, 0);
for (int &x : a) cin >> x;
map<int, int> mp;
int ans = 0;
for (int i = 0; i < n; ++i) {
ans += mp[a[i] - i];
++mp[a[i] - i];
}
cout << ans << '\n';
}
}