练习codeforces 1541B. Pleasant Pairs
题目如下
B. Pleasant Pairs
time limit per test2 seconds
memory limit per test256 megabytes
You are given an array 𝑎1,𝑎2,…,𝑎𝑛 consisting of 𝑛 distinct integers. Count the number of pairs of indices (𝑖,𝑗) such that 𝑖<𝑗 and 𝑎𝑖⋅𝑎𝑗=𝑖+𝑗.
Input
The first line contains one integer 𝑡 (1≤𝑡≤104) — the number of test cases. Then 𝑡 cases follow.
The first line of each test case contains one integer 𝑛 (2≤𝑛≤105) — the length of array 𝑎.
The second line of each test case contains 𝑛 space separated integers 𝑎1,𝑎2,…,𝑎𝑛 (1≤𝑎𝑖≤2⋅𝑛) — the array 𝑎. It is guaranteed that all elements are distinct.
It is guaranteed that the sum of 𝑛 over all test cases does not exceed 2⋅105.
Output
For each test case, output the number of pairs of indices (𝑖,𝑗) such that 𝑖<𝑗 and 𝑎𝑖⋅𝑎𝑗=𝑖+𝑗.
题目大意
定义目标指数满足𝑎𝑖⋅𝑎𝑗=𝑖+𝑗.,求出给定数组中这样的指数 (𝑖,𝑗) 的数量
解题思路
考虑到时间复杂度等,用朴素的暴力解法确实行不通,所以为了顺利ac,我们考虑在比较查找时减少次数
原型是a[i] * a[j] == i + j,
把它变形得到a[i] * a[j] - i == j,
我们又能得出a[i] * a[j] == i + j => i + j ≡ 0 (mod a[i]) => j = -I ( mod a[I] ) => j ≡ a[i] - i (mod a[I]) ;
所以在二重循环里的 j 的表达式可以是 j ≡ a[i] - i
同时 j 的 步长也可以变为 j += a[i];
这样就大大降低了枚举的个数与速度,
点击查看代码
for(int i = 1; i <= n; ++i){
for (long long j = a[i] - i; j <= n; j += a[i]) {
if (j <= i)
continue;
if (a[i] * a[j] == i + j)
count++;
}
}
完整代码
点击查看代码
#include <stdio.h>
int main() {
int t;
scanf("%d", &t);
while (t--){
int n;
scanf("%d", &n);
long long a[200005];
for(int i = 1; i <= n; ++i){
scanf("%lld", &a[i]);
}
long long count = 0;
for(int i = 1; i <= n; ++i){
for (long long j = a[i] - i; j <= n; j += a[i]){
if (j <= i)
continue;
if (a[i] * a[j] == i + j)
count++;
}
}
printf("%lld\n",count);
}
return 0;
}

浙公网安备 33010602011771号