B - Pleasant Pairs
Description
You are given an array a1, a2, …, an consisting of n distinct integers. Count the number of pairs of indices (i, j) such that i < j and ai ⋅ aj = i + j.
Input
The first line contains one integer t (1 ≤ t ≤ 10^4) — the number of test cases. Then t cases follow.
The first line of each test case contains one integer n (2 ≤ n ≤ 10^5) — the length of array a.
The second line of each test case contains n space separated integers a1, a2, …, an (1 ≤ ai ≤ 2 ⋅ n) — the array a. It is guaranteed that all elements are distinct.
It is guaranteed that the sum of n over all test cases does not exceed 2 ⋅ 10^5.
Output
For each test case, output the number of pairs of indices (i, j) such that i < j and ai ⋅ aj = i + j.
Example
input
3
2
3 1
3
6 1 5
5
3 1 5 9 2
output
1
1
3
Note
For the first test case, the only pair that satisfies the constraints is (1, 2), as a1 ⋅ a2 = 1 + 2 = 3
For the second test case, the only pair that satisfies the constraints is (2, 3).
For the third test case, the pairs that satisfy the constraints are (1, 2), (1, 5), and (2, 3).
题目大意:
给定数组a,求a中满足i < j 并且满足 ai ⋅ aj = i + j 的元素有几对。
题解:
首先想到用暴力求解,枚举数组中所有的数对逐一进行判断。
其中二重循环的时间复杂度太高(O(n2)),直接交就TLE了。
// 暴力无优化, TLE
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
ll a[N];
int main() {
ios::sync_with_stdio(false);
ll t;
cin >> t;
while (t --) {
ll n;
cin >> n;
for (ll i = 1; i <= n; i ++) cin >> a[i];
ll cnt = 0;
for (ll i = 1; i <= n; i ++) // O(n2)
for (ll j = i + 1; j <= n; j ++)
if (a[i] * a[j] == i + j) cnt ++;
cout << cnt << '\n';
}
return 0;
}
经过思考后可以发现第二重循环是可以进行优化的。
将需要满足的等式a[i] * a[j] = i + j移项可得 j = a[i] * a[j] - i 。
其中 a[i] 和 i 是已知的,我们可以枚举 a[j] 为1, 2, 3… 直到 j > n越界。
对应的循环就是 j 从a[i] - i开始,步长为 a[i] 的循环。其中要注意 j < i 的情况是不符合要求的,continue掉即可。
经过优化后的二重循环就能顺利AC了。
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
ll a[N];
int main() {
ios::sync_with_stdio(false);
ll t;
cin >> t;
while (t --) {
ll n;
cin >> n;
for (ll i = 1; i <= n; i ++) cin >> a[i];
ll cnt = 0;
for (ll i = 1; i <= n; i ++) {
for (ll j = a[i] - i; j <= n; j += a[i]) {
if (j <= i) continue;
if (a[i] * a[j] == i + j) cnt ++;
}
}
cout << cnt << '\n';
}
return 0;
}