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 见祖宗。

posted @ 2022-08-02 08:55  lsj2009  阅读(45)  评论(0)    收藏  举报