[NOIP2021]方差
Posted StaroForgin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[NOIP2021]方差相关的知识,希望对你有一定的参考价值。
方差
题解
T
i
w
A
i
r
O
A
O
\\rm\\colorblackT\\colorrediwAirOAO
TiwAirOAO:这不是
A
G
C
AGC
AGC上的经典题吗?
可我只打过一次AGC呀!!!
首先,我们无论怎么操作,整个序列都一定是不递减的。
显然,最开始是有
a
i
−
1
⩽
a
i
⩽
a
i
+
1
a_i-1\\leqslant a_i\\leqslant a_i+1
ai−1⩽ai⩽ai+1的,对
a
i
a_i
ai进行操作,使之变为
a
i
−
1
+
a
i
+
1
−
a
i
a_i-1+a_i+1-a_i
ai−1+ai+1−ai。
显然有
a
i
−
1
+
a
i
+
1
−
a
i
⩾
a
i
−
1
⇔
a
i
+
1
⩾
a
i
a_i-1+a_i+1-a_i\\geqslant a_i-1 \\Leftrightarrow a_i+1\\geqslant a_i
ai−1+ai+1−ai⩾ai−1⇔ai+1⩾ai,同理,
a
i
−
1
+
a
i
+
1
−
a
i
⩽
a
i
+
1
a_i-1+a_i+1-a_i\\leqslant a_i+1
ai−1+ai+1−ai⩽ai+1。
我们关注到它其实并不是只有大小顺序不变,不变的其实还有差分值。
(
a
i
−
1
+
a
i
+
1
−
a
i
)
−
a
i
−
1
=
a
i
+
1
−
a
i
,
a
i
+
1
−
(
a
i
−
1
+
a
i
+
1
−
a
i
)
=
a
i
−
a
i
−
1
(a_i-1+a_i+1-a_i)-a_i-1=a_i+1-a_i,a_i+1-(a_i-1+a_i+1-a_i)=a_i-a_i-1
(ai−1+ai+1−ai)−ai−1=ai+1−ai,ai+1−(ai−1+ai+1−ai)=ai−ai−1
一次操作实际上等价于交换旁边两个数的差分值,我们相当于要通过差分值的一个排序还原出我们的整个序列。
如果直接枚举显然是
n
!
n!
n!的,肯定不行。
但我们考虑我们怎样放可以使我们目标方差最小,显然肯定要尽可能地接近我们的平均数。
也就是,我们的曲线图像大概长这个样子,
也就是说,我们的差分值摆放应该从中间往两边递增。
否则的话,显然可以通过交换得到一组更小的解。
所以我们可以将差分值从小到大排序,在两端放差分值,还原到原序列上。
这明显使可以通过
d
p
dp
dp进行处理的。
根据逃跑,显然可以知道我们最后是要让
n
∑
i
=
1
n
a
i
2
−
(
∑
i
=
1
n
a
i
)
2
n\\sum_i=1^na_i^2-(\\sum_i=1^na_i)^2
n∑i=1nai2−(∑i=1nai)2最小,放到
d
p
dp
dp上,就去记录
∑
i
=
1
n
a
i
\\sum_i=1^na_i
∑i=1nai的和所对应的最小的
∑
i
=
1
n
a
i
2
\\sum_i=1^na_i^2
∑i=1nai2。
记
d
p
i
,
j
dp_i,j
dpi,j就是已经放完前
i
i
i个差分值,和为
j
j
j是平方和的最小值,
d
i
d_i
di是排序后第
i
i
i个差分值。
由于我们只会放在数列的第一个位置与最后一个位置,所以转移还是挺简单地。
要么就加上一个
(
∑
k
=
1
i
d
k
)
2
(\\sum_k=1^id_k)^2
(∑k=1idk)2,要么就相当于所有数都加上一个
d
i
d_i
di,需要加
i
d
i
2
+
2
d
i
∑
k
=
1
i
a
k
id_i^2+2d_i\\sum_k=1^ia_k
idi2+2di∑k=1iak。
可以直接背包转移。
时间复杂度
O
(
n
2
A
)
O\\left(n^2A\\right)
O(n2A),好像会被卡几个点。
没关系,我们发现事实上对于那些
n
n
n比较大的点
A
A
A都比较小,也就是说,非零的差分值是极少的。
对于
0
0
0的部分,我们是完全没必要处理的。
所有实际时间复杂度
O
(
n
A
min
(
n
,
A
)
)
O\\left(nA\\min(n,A)\\right)
O(nAmin(n,A)),完全可以过。
然而我考场上连差分都没想到。
源码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 10005
#define MAXM 500005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
Python无交互作用的二元方差分析