给出一串正整数数列以及一个正整数
C
C
C,要求计算出所有满足
A
−
B
=
C
A - B = C
A−B=C 的数对的个数(不同位置的数字一样的数对算不同的数对)。
输入格式
输入共两行。
第一行,两个正整数
N
,
C
N,C
N,C。
第二行,
N
N
N 个正整数,作为要求处理的那串数。
输出格式
一行,表示该串正整数中包含的满足
A
−
B
=
C
A - B = C
A−B=C 的数对的个数。
样例 #1
样例输入 #1
4 1
1 1 2 3
样例输出 #1
3
提示
对于
75
%
75\%
75% 的数据,
1
≤
N
≤
2000
1 \leq N \leq 2000
1≤N≤2000。
对于
100
%
100\%
100% 的数据,
1
≤
N
≤
2
×
1
0
5
1 \leq N \leq 2 \times 10^5
1≤N≤2×105,
0
≤
a
i
<
2
30
0 \leq a_i <2^{30}
0≤ai<230,
1
≤
C
<
2
30
1 \leq C < 2^{30}
1≤C<230。
第一种方法:
分析 如果决定枚举
A
A
A,那么问题就变成了统计数列中
B
+
C
B+C
B+C出现了多少次。把数列排序,那么
B
+
C
B+C
B+C会对应这个数列的连续一段。只要能快速找到这个连续端的左端点和右端点。也就是
B
+
C
B+C
B+C在有序数列中第一次出现和最后一次出现的位置,这道题目就可以迎刃而解。
当然,这道题还有一种(排序后)
O
(
n
)
O(n)
O(n)的做法:同样是寻找lower_bound和upper_bound的位置,可以发现随着被查询的
a
[
i
]
+
c
a[i]+c
a[i]+c的增大,lower_bound和upper_bound的位置也在变后,那么可以把这两个位置维护出来,即随着
a
[
i
]
+
c
a[i]+c
a[i]+c的增大而向后移动。因为这两个指针的移动次数不超过
n
n
n,所以这个算法是
O
(
n
)
O(n)
O(n)的,代码如下:
举个例子,假设
C
=
3
,
C=3,
C=3,数列是
2
,
5
,
3
,
7
,
5
,
2
,
4
,
8
2,5,3,7,5,2,4,8
2,5,3,7,5,2,4,8。将数列排序得到
2
,
2
,
3
,
4
,
5
,
5
2,2,3,4,5,5
2,2,3,4,5,5。对于序列中的一个数
s
[
i
]
s[i]
s[i],想要快速找到
s
[
i
]
−
C
s[i]-C
s[i]−C。如果
s
[
i
]
−
C
s[i]-C
s[i]−C 。如果
s
[
i
]
−
C
s[i]-C
s[i]−C这个数字存在的话,一定在排序后的数列中是连续。维护两个指针,左指针
l
l
l和右指针
r
r
r使得
s
[
l
]
s[l]
s[l]是首个大于等于
s
[
i
]
−
C
s[i]-C
s[i]−C的数,
s
[
r
]
s[r]
s[r]是首个大于
s
[
i
]
−
C
s[i]-C
s[i]−C的数。这样,从
s
[
l
]
s[l]
s[l]到
s
[
r
−
1
]
s[r-1]
s[r−1]都是等于
s
[
i
]
−
C
s[i]-C
s[i]−C的数字,即等于
s
[
i
]
−
C
s[i]-C
s[i]−C的数字个数有
r
−
1
r-1
r−1个,累加进答案中。
s
[
i
]
−
C
s[i]-C
s[i]−C是越来越大,所以
l
l
l和
r
r
r都会越来越往右
i
i
i
0
1
2
3
4
5
6
7
排序后的
s
[
i
]
s[i]
s[i]
2
2
3
4
5
5
7
8
l
=
r
=
0
l=r=0
l=r=0
s
[
0
]
s[0]
s[0]
2
2
3
4
5
5
7
8
l
=
r
=
0
l=r=0
l=r=0
s
[
1
]
s[1]
s[1]
2
2
3
4
5
5
7
8
l
=
r
=
0
l=r=0
l=r=0
s
[
2
]
s[2]
s[2]
2
2
3
4
5
5
7
8
l
=
r
=
0
l=r=0
l=r=0
s
[
3
]
s[3]
s[3]
2
2
3
4
5
5
7
8
l
=
0
;
r
=
2
;
l=0;r=2;
l=0;r=2;答案增加
r
−
l
=
2
r-l=2
r−l=2
s
[
4
]
s[4]
s[4]
2
2
3
4
5
5
7
8
l
=
0
;
r
=
2
;
l=0;r=2;
l=0;r=2;答案增加
r
−
l
=
2
r-l=2
r−l=2
s
[
5
]
s[5]
s[5]
2
2
3
4
5
5
7
8
l
=
0
;
r
=
2
;
l=0;r=2;
l=0;r=2;答案增加
r
−
l
=
2
r-l=2
r−l=2
s
[
6
]
s[6]
s[6]
2
2
3
4
5
5
7
8
l
=
3
;
r
=
4
;
l=3;r=4;
l=3;r=4;答案增加
r
−
l
=
1
r-l=1
r−l=1
s
[
7
]
s[7]
s[7]
2
2
3
4
5
5
7
8
l
=
4
;
r
=
6
;
l=4;r=6;
l=4;r=6;答案增加
r
−
l
=
2
r-l=2
r−l=2