∑ a = 1 n ∑ b = 1 n ∑ c = 1 n ∑ d = 1 n ∑ e = 1 n ∑ f = 1 n ∑ g = 1 n ∑ h = 1 n ∑ i = 1 n ∑ j = 1 n ∑ k = 1 n ∑ l = 1 n ∑ m = 1 n ∑ n = 1 n ∑ o = 1 n ∑ p = 1 n ∑ q = 1 n ∑ r = 1 n ∑ s = 1 n ∑ t = 1 n ∑ u = 1 n ∑ v = 1 n ∑ w = 1 n ∑ x = 1 n ∑ y = 1 n ∑ z = 1 n \mathcal{\sum\limits_{a=1}^n\sum\limits_{b=1}^n\sum\limits_{c=1}^n\sum\limits_{d=1}^n\sum\limits_{e=1}^n\sum\limits_{f=1}^n\sum\limits_{g=1}^n\sum\limits_{h=1}^n\sum\limits_{i=1}^n\sum\limits_{j=1}^n\sum\limits_{k=1}^n\sum\limits_{l=1}^n\sum\limits_{m=1}^n\sum\limits_{n=1}^n\sum\limits_{o=1}^n\sum\limits_{p=1}^n\sum\limits_{q=1}^n\sum\limits_{r=1}^n\sum\limits_{s=1}^n\sum\limits_{t=1}^n\sum\limits_{u=1}^n\sum\limits_{v=1}^n\sum\limits_{w=1}^n\sum\limits_{x=1}^n\sum\limits_{y=1}^n\sum\limits_{z=1}^n} a=1∑nb=1∑nc=1∑nd=1∑ne=1∑nf=1∑ng=1∑nh=1∑ni=1∑nj=1∑nk=1∑nl=1∑nm=1∑nn=1∑no=1∑np=1∑nq=1∑nr=1∑ns=1∑nt=1∑nu=1∑nv=1∑nw=1∑nx=1∑ny=1∑nz=1∑n
注意有多组数据。
题目摆了一个大大的
(
∑
i
=
1
k
C
i
)
2
+
M
\mathcal{(\sum\limits_{i=1}^k C_i)^2+M}
(i=1∑kCi)2+M
前缀和、区间和记为
S
(
i
)
\mathcal{S(i)}
S(i)和
S
(
i
,
j
)
\mathcal{S(i,j)}
S(i,j)。
非常显然的
d
p
\mathcal{dp}
dp,先裂一个柿子
F
(
i
)
=
m
i
n
{
F
(
j
)
+
c
o
s
t
(
j
+
1...
i
)
}
\mathcal{F(i)=min\{F(j)+cost(j+1...i)\}}
F(i)=min{F(j)+cost(j+1...i)}也即
F
(
i
)
=
m
i
n
{
F
(
j
)
+
M
+
[
S
(
i
)
−
S
(
j
−
1
)
]
2
}
,
j
∈
[
1
,
i
)
\mathcal{F(i)=min\{F(j)+M+[S(i)-S(j-1)]^2\},j\in[1,i)}
F(i)=min{F(j)+M+[S(i)−S(j−1)]2},j∈[1,i)这布星
Θ
(
n
2
)
\mathcal{\Theta(n^2)}
Θ(n2)
上面的柿子比较好康,容易联想到单调队列
F
(
i
)
=
m
a
x
/
m
i
n
{
F
(
j
)
+
G
(
j
)
}
\mathcal{F(i)=max/min\{F(j)+G(j)\}}
F(i)=max/min{F(j)+G(j)}。
然鹅形式是
F
(
i
)
=
m
a
x
/
m
i
n
{
F
(
j
)
+
G
(
i
,
j
)
}
\mathcal{F(i)=max/min\{F(j)+G(i,j)\}}
F(i)=max/min{F(j)+G(i,j)};怎么拌?
这一部分讨论的不是常规的单调队列+斜率优化,可以先看下面的再上来
没办法化成别的什么形式。有没有决策单调性?
我们现在
i
−
1
\mathcal{i-1}
i−1从
j
\mathcal{j}
j转移过来,
i
\mathcal{i}
i从
j
′
\mathcal{j'}
j′转移过来,有没有
j
′
≥
j
\mathcal{j'\ge j}
j′≥j、
比如
(
∑
i
=
1
k
C
i
)
2
+
M
\mathcal{(\sum\limits_{i=1}^k C_i)^2+M}
(i=1∑kCi)2+M现在
+
+
i
\mathcal{++i}
++i变成
(
∑
i
=
1
k
C
i
)
2
+
2
(
∑
i
=
1
k
C
i
)
C
i
+
1
+
C
i
+
1
2
+
M
\mathcal{(\sum\limits_{i=1}^kC_i)^2+2(\sum\limits_{i=1}^kC_i)C_{i+1}+C_{i+1}^2+M}
(i=1∑kCi)2+2(i=1∑kCi)Ci+1+Ci+12+M
如果多分一份就是
(
∑
i
=
1
k
C
i
)
2
+
C
i
+
1
2
+
2
M
\mathcal{(\sum\limits_{i=1}^k C_i)^2+C_{i+1}^2+2M}
(i=1∑kCi)2+Ci+12+2M,
Δ
=
M
−
2
(
∑
i
=
1
k
C
i
)
C
i
+
1
\mathcal{\Delta=M-2(\sum\limits_{i=1}^kC_i)C_{i+1}}
Δ=M−2(i=1∑kCi)Ci+1
多分一份优即
Δ
≤
0
\mathcal{\Delta\le0}
Δ≤0那么已经多分一份了之后决策就不会把多分这一份的时间推前。
因为推前了,前面亏、后面也亏。推后倒是有可能的。
于是我们
f
a
\mathcal{fa}
fa现了这样一个十分简单好写的决策单调性——这题连决策点都是单调的
然后就可以愉快
Θ
(
n
)
\mathcal{\Theta(n)}
Θ(n)。
我不会证所以这些都是扯淡,大家可以自己试一试
决策单调性是不是看起来有点像贪心啊
了解斜率优化过后这种做法可能更好理解。
如果把斜率优化那个过程模拟一下,又因为这道题 F u n c i o n O f ( k ) \mathcal{FuncionOf(k)} FuncionOf(k)有个单调性,
不难发现决策点一定是越来越靠后的。所以……
事实上(至少对于这道题目)好像没有必要开个单调队列吧?
嗯嗯?唔呣???
#include<cstdio>
long long s[500005], f[500005];
int n, m;
int main() {
while (~scanf("%d%d", &n, &m)) {
for (int i(1); i <= n; s[i] += s[i-1], ++i) scanf("%lld", &s[i]);
for (int i(1), p(0); i <= n; ++i) {
f[i] = s[i] * s[i] + m;
for (int j(p); j < i; ++j) {
long long temp(f[j] + (s[i] - s[j]) * (s[i] - s[j]) + m);
if (temp <= f[i]) f[i] = temp, p = j;
}
} printf("%lld\n", f[n]);
} return 0;
}
斜率优化
式子形如
F
(
i
)
=
m
i
n
{
F
(
j
)
+
G
(
i
,
j
)
}
\mathcal{F(i)=min\{F(j)+G(i,j)\}}
F(i)=min{F(j)+G(i,j)}
现在我们要找到用前面的哪个决策来更新当前决策最优
这个最优的定义是相对的,并不好维护。能够降低它的复杂度意味着还有别的性质。
d
p
\mathcal{dp}
dp能够有的特殊性质倒不多,可以考虑到的比如说决策单调性?
决策单调性也就是说比如现在
a
<
b
<
c
<
d
\mathcal{a<b<c<d}
a<b<c<d,
如果用
b
\mathcal{b}
b来更新
c
\mathcal{c}
c最优,那么
a
\mathcal{a}
a更新
d
\mathcal{d}
d至少不比用
c
\mathcal{c}
c好。
简单的决策单调性比如单调队列、四边形不等式一类的。
但是这道题目带了一个
G
(
i
,
j
)
\mathcal{G(i,j)}
G(i,j)。
本题的决策单调性可以乱搞瞎蒙意证得到,就不多解释了(
G
(
i
,
j
)
\mathcal{G(i,j)}
G(i,j)怎么搞?
这么讲可能都比较模糊,我们考虑一下是不是能够用更加直观的形式来表示决策单调性。
我们可以把决策看作多个不同的点,把前面的点更新后面的点的优劣程度看作斜率
为什么这么看?大概脑内模拟一下,维护决策单调性的感觉跟动态维护凸包很像吧?
在维护凸包之前先来讨论一下这个式子要怎么转化成斜率的形式、
用
i
(
x
i
,
y
i
)
\mathcal{i(x_i,y_i)}
i(xi,yi)更新
k
(
x
k
,
y
k
)
\mathcal{k(x_k,y_k)}
k(xk,yk)比用
j
(
x
j
,
y
j
)
\mathcal{j(x_j,y_j)}
j(xj,yj)更好
首先容易得到
F
(
i
)
+
M
+
S
2
(
i
+
1
,
k
)
<
F
(
j
)
+
M
+
S
2
(
j
+
1.
k
)
\mathcal{F(i)+M+S^2(i+1,k)<F(j)+M+S^2(j+1.k)}
F(i)+M+S2(i+1,k)<F(j)+M+S2(j+1.k)
要转化为
y
(
i
)
−
y
(
j
)
x
(
i
)
−
x
(
j
)
(
<
/
>
)
F
u
n
c
t
i
o
n
O
f
(
k
)
\mathcal{\dfrac{y(i)-y(j)}{x(i)-x(j)}\quad(</>)\quad FunctionOf(k)}
x(i)−x(j)y(i)−y(j)(</>)FunctionOf(k):化式子。过程不难自己推(
先变成 F ( i ) − F ( j ) < [ S ( k ) − S ( j − 1 ) ] 2 − [ S ( k ) − S ( i − 1 ) ] 2 \mathcal{F(i)-F(j)<[S(k)-S(j-1)]^2-[S(k)-S(i-1)]^2} F(i)−F(j)<[S(k)−S(j−1)]2−[S(k)−S(i−1)]2
又变成 F ( i ) − F ( j ) < − 2 S ( k ) S ( j − 1 ) + S 2 ( j − 1 ) + 2 S ( k ) S ( i − 1 ) − S 2 ( i − 1 ) \mathcal{F(i)-F(j)<-2S(k)S(j-1)+S^2(j-1)+2S(k)S(i-1)-S^2(i-1)} F(i)−F(j)<−2S(k)S(j−1)+S2(j−1)+2S(k)S(i−1)−S2(i−1)
再变成 F ( i ) + S 2 ( i − 1 ) − F ( j ) − S 2 ( j − 1 ) < 2 [ S ( i − 1 ) − S ( j − 1 ) ] S ( k ) \mathcal{F(i)+S^2(i-1)-F(j)-S^2(j-1)<2[S(i-1)-S(j-1)]S(k)} F(i)+S2(i−1)−F(j)−S2(j−1)<2[S(i−1)−S(j−1)]S(k)
最后得到
[
F
(
i
)
+
S
2
(
i
−
1
)
]
−
[
F
(
j
)
+
S
2
(
j
−
1
)
]
S
(
i
−
1
)
−
S
(
j
−
1
)
<
2
S
(
k
)
\mathcal{\dfrac{[F(i)+S^2(i-1)]-[F(j)+S^2(j-1)]}{S(i-1)-S(j-1)}<2S(k)}
S(i−1)−S(j−1)[F(i)+S2(i−1)]−[F(j)+S2(j−1)]<2S(k)
分母(警觉) 小心不要devided by zero(
那么
y
i
=
F
(
i
)
+
S
2
(
i
−
1
)
,
x
i
=
S
(
i
−
1
)
\mathcal{y_i=F(i)+S^2(i-1),x_i=S(i-1)}
yi=F(i)+S2(i−1),xi=S(i−1)
好像成功了(
注意上面提到的这种形式实质上还没有利用到决策单调性;
然而这个时候我们已经可以做初步优化了。
二分查找小于 k \mathcal{k} k的凸集里,斜率 < 2 S ( k ) \mathcal{<2S(k)} <2S(k)且最大的边。
于是就可以用这个边靠后的那个点来更新 k \mathcal{k} k。这个要多一个 l o g \mathcal{log} log;
因为显然这道题的
F
u
n
c
t
i
o
n
O
f
(
k
)
=
2
S
(
k
)
\mathcal{FunctionOf(k)=2S(k)}
FunctionOf(k)=2S(k)显然单调不递减并且x(i)单调
然后就可以单调队列
每次得到
F
(
i
)
\mathcal{F(i)}
F(i)前删掉队头不优于后面一个点的点(边斜率过小);
向凸包中加入
i
\mathcal{i}
i点前删掉队尾那些会被新凸包包含的点(边斜率过大);
虽然感觉很显然但是这么说起来可能有点奇怪,斜率又要小又不能小的?
也许画个图比较好理解、或者说,
其中第一种情况(边斜率过小)在没有单调性的时候是不能删除然后直接用队头计算 F ( i ) \mathcal{F(i)} F(i)的
(至于没有单调性的时候具体要怎么搞上面也说过了,二分)
也就是说第一种情况的删除是对复杂度的优化。
所以并不是被限制不能小,而是我们主动把没必要计算的那一部分删除掉;
第二种情况为什么要维护凸壳应该不用多解释大家都是茗白人()
然后就可以写单调队列了。
我不好画图,看大米饼的博客可能比较好懂一点
实际上理解为化成
y
=
k
x
+
b
\mathcal{y=kx+b}
y=kx+b求
m
a
x
/
m
i
n
(
b
)
\mathcal{max/min(b)}
max/min(b)也比较好操作。
比较斜率的部分改成用叉积也是可以的。
代码:卜
总的来说适用范围更广的还是二分,不过多了一个
l
o
g
\mathcal{log}
log
对于横坐标都不单调的那些可以搞离线啊搞
c
d
q
\mathcal{cdq}
cdq啊搞
S
p
a
l
y
\mathcal{Spaly}
Spaly啦比如
b
z
o
j
1492
\mathcal{bzoj1492}
bzoj1492