查找满足A[i]+A[j]=j-i的数对(i,j)数量

查找满足A[i]+A[j]=j-i的数对(i,j)数量

问题描述

给定\( N \)个数字组成的数列\( {A_N} \),\( A_i \)下标从1开始,求出有多少对\( (i,j) \) 使 \( A_i+A_j = j-i \)成立。

https://vjudge.net/problem/AtCoder-5309

例如对于数列 \( \{2, 3, 3, 1, 3, 1\} \),有三个数对满足条件:
\[A_1+A_4=3=4-1 \\
A_2+A_6=4 = 6-2 \\
A_4+A_6=2=6-4 \]
所以此时结果为3.

问题分析

用枚举当然很简单,可是只有小数据量时能通过。由于此题给出的数列长度达\( 2\times 10^5 \),\(O(N^2) \)的枚举法会超时。

Haskell

要想办法优化到最多 \( O(N \log(N) )\)的时间,也就是想办法将逐元素的顺序查找改为二分查找。

我们要对数列\( A_N \)中的两个元素\( A_i,A_j\)符合\[ A_i+A_j = j-i \]

移项即\[ i+A_i = j-A_j \]

令\( L_i = i+A_i \), \(R_i = i-A_i \),我们只需要对每个\( L \)中的元素\( L_i \),查找\( R \)中有多少个与 \( L_i \) 相等的即可。估算一下复杂度,对R进行1次排序并进行N次查找, 理论上可以在 \( O(N \log(N) )\)的时间完成。

此题\( A_i \)达\( 10^9 \),且\( N \) 最大\( 2\times 10^5\),在计算\( L_i = i+A_i \) 时可能造成int范围溢出,所以将数组设为long long类型

参考程序

C++

用Python写时间比较极限,提交了一次运行1996ms,时限就2000ms

Python

Haskell写了一样的方法但是只有小数据能过,还需要再进一步学习

Haskell

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注