CF1922C的题解

(一)

ij 有两种走法,一种是用 ajai 的代价,一种是用 1 的代价,前提是 ji 最近的。

显然如果符合条件选第二种。

先考虑从左向右走。(和从右向左相同)

考虑走到了节点 i,如果 ai+1ai>aiai1,那么花费 1 的代价向右走,否则花费 ai+1ai 的代价向右走。

用类似于前缀和的方法统计,由于每一步用哪种与前面无关(肯定能选第二种就第二种),那么只用从左到右,从右到左都扫一遍即可。

ltori 表示从 1 走到 i 最少代价。

lr 最少代价即为 ltorrltorl

(二)

AC 代码。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n,l,r,q,a[100010],ltor[100010],rtol[100010];
signed main(){
	scanf("%lld",&t);
	while(t--){
		scanf("%lld",&n);
		for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
		for(int i=2;i<=n;i++){
			if(a[i]-a[i-1]<=a[i-1]-a[i-2]||i==2)ltor[i]=ltor[i-1]+1;
			else ltor[i]=ltor[i-1]+a[i]-a[i-1];
		}
		for(int i=n-1;i>=1;i--){
			if(a[i+1]-a[i]<=a[i+2]-a[i+1]||i==n-1)rtol[i]=rtol[i+1]+1;
			else rtol[i]=rtol[i+1]+a[i+1]-a[i];
		}
		scanf("%lld",&q);
		while(q--){
			scanf("%lld%lld",&l,&r);
			if(l<r)printf("%lld\n",ltor[r]-ltor[l]);
			else printf("%lld\n",rtol[r]-rtol[l]);
		}
	}
	return 0;
}
```
posted @   Jerry_heng  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示