(暂时未完成)
系列说明&文章概要
这个系列是因为笔者在赛前发现实力过于蒟蒻,遂准备一边听课一边写笔记
这篇文章主要介绍多种线性优化策略,配合例题讲解,故题目会比较多,强烈建议注册洛谷的账号。
双指针
EG1:A-B 数对
题意概要:
给定一个数列和一个正整数 C,求数对
(
A
,
B
)
(A,B)
(A,B) 的个数使得
A
−
B
=
C
A - B = C
A−B=C。
Sol1:
首先暴力做是
O
(
n
2
)
O(n^2)
O(n2) 的,能拿
75
%
75\%
75% 的分数。
然后考虑怎样做的更好。
注意到数列的顺序与答案无关。
那么将数列排序为不降数列,然后我们发现相同的数跑到了一起,更加好的是,如果存在一组
(
i
,
j
,
i
′
,
j
′
)
(i,j,i',j')
(i,j,i′,j′) 使得(设原数列为
a
a
a)
a
i
−
a
j
=
C
a_i - a_j = C
ai−aj=C 且
a
i
′
−
b
j
′
=
C
a_{i'} - b_{j'} = C
ai′−bj′=C 且
i
>
i
′
i > i'
i>i′ 那么一定有
j
>
j
′
j > j'
j>j′。
考虑利用这个性质,具体的,我们考虑枚举
i
i
i 的值,然后算出
1
≤
j
≤
i
1 \le j \le i
1≤j≤i 时满足要求的数对个数。
注意到如果我们观察
j
j
j 变量的动向,会发现
j
j
j 的移动一直是朝着同一方向的。(由上面的性质可得)
那么直接枚举
i
i
i 的值,
i
i
i 变化时暴力更新
j
j
j 的值,注意到数列当中的每个数最多被
i
i
i 和
j
j
j 各扫到一次,故时间复杂度是
O
(
n
)
O(n)
O(n) (过程)
+
+
+
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)(排序)
=
=
=
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)。
上面介绍的算法就是双指针算法,注意到它可以很方便的把一个 O ( n 2 ) O(n^2) O(n2) 的问题转化为一个 O ( n ) O(n) O(n) 从而解决问题。