P3406 海底高铁,差分
题目描述
题目背景
题目描述
该铁路经过 NN 个城市,每个城市都有一个站。不过,由于各个城市之间不能协调好,于是乘车每经过两个相邻的城市之间(方向不限),必须单独购买这一小段的车票。第 ii 段铁路连接了城市 ii 和城市 i+1(1\leq i<N)i+1(1≤i<N)。如果搭乘的比较远,需要购买多张车票。第 ii 段铁路购买纸质单程票需要 A_iA**i 博艾元。
虽然一些事情没有协调好,各段铁路公司也为了方便乘客,推出了 IC 卡。对于第 ii 段铁路,需要花 C_iC**i 博艾元的工本费购买一张 IC 卡,然后乘坐这段铁路一次就只要扣 B_i(B_i<A_i)B**i(B**i<A**i) 元。IC 卡可以提前购买,有钱就可以从网上买得到,而不需要亲自去对应的城市购买。工本费不能退,也不能购买车票。每张卡都可以充值任意数额。对于第 ii 段铁路的 IC 卡,无法乘坐别的铁路的车。
Uim 现在需要出差,要去 MM 个城市,从城市 P_1P1 出发分别按照 P_1,P_2,P_3,\cdots,P_MP1,P2,P3,⋯,P**M 的顺序访问各个城市,可能会多次访问一个城市,且相邻访问的城市位置不一定相邻,而且不会是同一个城市。
现在他希望知道,出差结束后,至少会花掉多少的钱,包括购买纸质车票、买卡和充值的总费用。
输入格式
第一行两个整数,N,MN,M。
接下来一行,MM 个数字,表示 P_iP**i。
接下来 N-1N−1 行,表示第 ii 段铁路的 A_i,B_i,C_iA**i,B**i,C**i。
输出格式
一个整数,表示最少花费
输入输出样例
输入 #1复制
9 10 3 1 4 1 5 9 2 6 5 3 200 100 50 300 299 100 500 200 500 345 234 123 100 50 100 600 100 1 450 400 80 2 1 10
输出 #1复制
6394
说明/提示
22 到 33 以及 88 到 99 买票,其余买卡。
对于 30%30% 数据 M=2M=2。
对于另外 30%30% 数据 N\leq1000,M\leq1000N≤1000,M≤1000。
对于 100%100% 的数据 M,N\leq 105,A_i,B_i,C_i\le105M,N≤105,A**i,B**i,C**i≤105。
算法求解
分析
用差分来统计每一段经过的次数,统计完了之后比较是买卡便宜还是买票便宜
注意
- 根据行程进行差分加和的时候,先判断一下两个站点序号的大小
- 最后的结果res用long long 类型,并且res计算过程中也需要用long long强制转化
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int A[N], B[N], C[N];
int b[N]; // 表示差分
int path[N]; // 表示经过的路径
int n, m;
void add(int l, int r)
{
b[l] += 1;
b[r+1] -= 1;
}
int main()
{
scanf("%d%d",&n, &m);
for(int i = 0; i < m; i++) scanf("%d", &path[i]);
// 初始是0,不用构造差分
for(int i = 1; i <= n-1; i++)
{
scanf("%d%d%d", &A[i], &B[i], &C[i]); // i -> i+1
}
// 对每一段 path[i] -> path[i+1]
for(int i = 0; i < m-1; i++)
{
int x = path[i], y = path[i+1];
if(x > y) swap(x, y);
add(x, y-1);
}
// 求前缀和, b[i]表示每段站经过的次数
for(int i = 1; i <= n-1; i++) b[i] += b[i-1];
LL res = 0;
for(int i = 1; i <= n-1; i++)
{
LL fee1 = (LL)A[i] * b[i];
LL fee2 = (LL)B[i] * b[i] + C[i];
if(fee1 > fee2) res += fee2;
else res += fee1;
}
cout << res << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现