Luogu8092 solution
Problem
link->https://www.luogu.com.cn/problem/P8092。
Solution
这真是道黄题?(超小声。
看一眼数据范围:\(n\le 10^5,h_i\le 10^9\),这不是 \(O(n)\) 就是 \(O(n\log{n})\) 了。
容易发现,当 \(2 \mid n\) 时,答案满足单调性;但 \(n\) 为奇数就不一定了。
我们考虑 \(O(n)\) 解。
可以看出,如果第 \(i\) 个位置的奶牛饥饿度减少,那么它一定是与 \(i-1\) 或 \(i+1\) 号奶牛一起进食的。我们设 \(f_i\) 为第 \(i\) 号奶牛与第 \(f_{i+1}\) 号奶牛一起进食的数量(不是 \(i\) 和 \(i+1\) 进食的总数),又设 \(x\) 为奶牛们最后保持的饥饿度,那么
\[x=h_i-f_{i-1}-f{i}
\]
(\(f_0=f_n=0\))
\[f_i=h_i-f_{i-1}-x
\]
\[f_1=h_1-x
\]
\[f_2=h_2-f_1-x=h_2-h_1+x-x=h_2-h_1
\]
\[f_3=h_3-f_2-x=h_3-h_2+h_1-x
\]
\[......
\]
\[f_{n-1}=h_{n-1}-f_{n-2}=...
\]
\[f_n=h_n-f_{n-1}=...
\]
将他们列出来:
\[f_1=h_1-x
\]
\[f_2=h_2-h_1
\]
\[f_3=h_3-h_2+h_1-x
\]
发现规律:
\[f_n=\begin{cases}\sum\limits_{i=1}^n=\begin{cases}+h_i\quad2\nmid i\\-h_i\quad2\mid i\end{cases}-x\qquad2\nmid n\\\sum\limits_{i=1}^n=\begin{cases}-h_i\quad2\nmid i\\+h_i\quad2\mid i\end{cases}\qquad2\mid n\end{cases}
\]
同时,
\[h_n-f_{n-1}-x=0
\]
\[\begin{cases}x=+h_1-h_2+h_3-...+h_{n-2}-h_{n-1}+h_n\qquad2\nmid n\\0=-h_1+h_2-h_3+...+h_{n-2}-h_{n-1}+h_n\qquad2\mid n\end{cases}
\]
通过上述方程,我们可以直接计算出 \(n\) 为奇数的 \(x\),然后计算出答案(若 \(x\) 为负,则答案为 \(-1\))。
if(n&1) {
int x=0,ans=0;
for(int i=1;i<=n;i++) //根据公式计算 x
x+=(i&1? 1:-1)*h[i];
if(x<0) return -1; //x 为负
for(int i=1;i<n;i++) {
f[i]=h[i]-f[i]-x; ans+=f[i]; if(f[i]<0) return -1; //计算 f[i] 并累加,同时 f[i] 必须大于等于 0,否则无解
}
return ans<<1; //由于 f[i] 为“第 i 头和 i+1 头的进食量”,所以需*2
}
而当 \(n\) 为偶数时,我们并不能计算出 \(x\),但如果上式答案不为 \(0\),则不能完成任务,答案为 \(-1\)。
int x=0;
for(int i=1;i<=n;i++)
x+=(i&1? -1:1)*h[i];
if(x) return -1;
可以看出,如果我们确定 \(x\),那么只有 \(f_1,f_3,...,f_{n-1}\) 会受到影响,而 \(f_i\) 不能为负(必须喂至少奶牛 \(0\) 袋玉米,而每喂一袋,饥饿度必 \(-1\)),那么我们只能设定 \(x\) 为当前的 \(\min\limits_{1\le i\le n,2 \nmid i}(f_i)\),当前 \(f_i\) 为 \(h_i-f_{i-1}\)。
int ans=0,m=INF;
for(int i=1;i<n;i++) {
f[i]=h[i]-f[i]; if(f[i]<0) return -1;
}
for(int i=1;i<n;i++) m=min(f[i],m);
for(int i=1;i<n;i++) ans+=f[i]-m;
return ans<<1;
最后留一句话:十年 OI 一场空,不开 long long
见祖宗。