首页 > 其他分享 >洛谷P3046 海底高铁 巧用差分统计经过区间次数

洛谷P3046 海底高铁 巧用差分统计经过区间次数

时间:2023-11-08 15:36:48浏览次数:34  
标签:洛谷 int ll 差分 次数 P3046 路段 include

洛谷P3046 海底高铁 -差分统计经过区间次数

题目贴在这里P3406 海底高铁 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

分析

本题题干很长,但是题意理解很简单。就是给定n个节点,每次仅能在相邻的两个节点之间移动,且任意两个节点之间的高铁费用也不一样。

依据题意,假设从3节点到1节点,我们要走两段路,即从3->2 , 2->1。

对于每段路,有两种收费模式,一个是直接买票,另一个是办卡。
最后要求我们给出最少的花费

显然我们可以先根据路线统计出通过各个路段的次数。
如从3->1,经过1-2路段次数加1,经过2-3的次数加1。
最后用各个路段经过次数乘以花费,即sum = max(cnt * 买票 ,cnt * 办卡花费 + 工本费)

但是如果我们遍历区间来进行一段一段的计数的话,时间复杂度有点高,大概是O(N2)

仔细观察,统计3->1经过的路段的次数,无非是将区间1-3或者说第一段路到第二短路所有元素加1(此时编号1-2)。要简化这种操作,只需要求出原路段数组的差分数组,对其差分数组进行操作即可,最后再求一遍前缀和,即可得出加1后的路段次数数组。

而且更加方便的是,初始时所有路段经过次数都为0,故其差分数组就是一个元素都为0 的数组。所以我们只需要读入每次经过的区间,对差分数组进行插入操作即可。读入所有区间之后在进行求前缀和,这样就得到每段路所经过的次数了。

AC代码如下

#include<iostream>
#include<vector>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int F = 1e5 + 10;
ll N, M;
ll P[F];
ll All[F];
ll D[F];
ll A[F];
ll B[F];
ll C[F];
//差分
void Insert(int l ,int r)
{
	D[l] += 1;
	D[r + 1] -= 1;
}
int main()
{
	cin >> N >> M;
	for (int i = 1; i <= M; i++)
	{
		cin >> P[i];
	}
	for (int i = 1; i <= N - 1; i++)
	{
		cin >>A[i]>>B[i]>>C[i];
	}
	for (int i = 1; i <= M-1; i++)
	{
		int x = P[i];
		int y = P[i + 1];
		if (x > y)swap(x, y);
		y -= 1;
		Insert(x, y);
	}
	for (int i = 1; i <= N-1; i++)
	{
		All[i] = All[i-1]+D[i];
	}
	ll Sum = 0;
	for (int i = 1; i <= N-1; i++)
	{
		Sum += min(All[i] * A[i],All[i]*B[i]+C[i]);
	}
	cout << Sum;
	return 0;
}

标签:洛谷,int,ll,差分,次数,P3046,路段,include
From: https://www.cnblogs.com/CrescentWind/p/17813965.html

相关文章

  • 【洛谷 P4414】[COCI2006-2007#2] ABC 题解(排序)
    [COCI2006-2007#2]ABC题面翻译【题目描述】三个整数分别为。这三个数字不会按照这样的顺序给你,但它们始终满足条件:。为了看起来更加简洁明了,我们希望你可以按照给定的顺序重新排列它们。【输入格式】第一行包含三个正整数,不一定是按这个顺序。这三个数字都小于或等于。第二行包......
  • 洛谷内卷监视工具(升级版)
    较原版内卷监视工具,增加了一下功能:计分板(宏观掌控他人的卷题数量和难度分布)多次连续AC相同题目去重可能会不定时更新有什么建议可以提出varuserlist=["ricky_lin","Query_Failed","The_Last_Candy","Jeefy","Rairn","hfjh","fsfdgdg","aish......
  • [洛谷 P3481] [BZOJ1118] [POI2009] PRZ-Algorithm Speedup
    题目描述你需要计算一个函数\(F(x,y)\),其中\(x,y\)是两个正整数序列。boolF(std::vector<int>x,std::vector<int>y){if(W(x).size()!=W(y).size())returnfalse;if(W(x).size()==1)returntrue;returnF(p(x),p(y))&&F(s(x),s(y));}\(W......
  • 前缀和+差分数组
    一、一维数组度前缀和--固定数组查询区间和1.1定义对于给定一个数组arr(下标从0开始),它的前缀和S[i]表示从arr[0]到arr[i]元素总和。1.2构造前缀和S[i]=S[i-1]+arr[i-1]1.3应用-求某个区间的和计算区间[i,j]的元素和=>arr[i]+arr[i+1]+arr[i+2]+……+a......
  • 【洛谷 P1046】[NOIP2005 普及组] 陶陶摘苹果 题解(比较)
    [NOIP2005普及组]陶陶摘苹果题目描述陶陶家的院子里有一棵苹果树,每到秋天树上就会结出个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。现在已知个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的......
  • 【进阶算法】差分
    差分是一种类似于前缀和的编码技巧,可以快速实现对数组某个区间的所有元素增加或减少一个值。一、差分数组示例:数组arr=[8,1,3,-2,5,0,-3,6],输入m个操作,每个操作输入(L,R,val),表示对数组的[L,R]区间中每个元素增加val,要求输出最后的arr数组。比如,第1次操作,输入(0,2......
  • 【洛谷 P1909】[NOIP2016 普及组] 买铅笔 题解(打擂台法)
    [NOIP2016普及组]买铅笔题目背景NOIP2016普及组T1题目描述P老师需要去商店买支铅笔作为小朋友们参加NOIP的礼物。她发现商店一共有种包装的铅笔,不同包装内的铅笔数量有可能不同,价格也有可能不同。为了公平起见,P老师决定只买同一种包装的铅笔。商店不允许将铅笔的包装......
  • 【LGR-161-Div.3】洛谷基础赛 #4 P9688 Colo.
    原题链接:P9688Colo.很显然,能够共存的颜色一定不会相交,所以可以记录每个颜色最左边的位置和最右边的位置,我们对于每个颜色只考虑,这个颜色左边的可以和这个颜色共存的额颜色用f[i][j]表示当前考虑i这种颜色,选i这种颜色,然后在i这种颜色之前(包括这种颜色)一共选了j种颜色的最大价值......
  • 【洛谷 P1085】[NOIP2004 普及组] 不高兴的津津 题解(打擂台法)
    [NOIP2004普及组]不高兴的津津题目描述津津上初中了。妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班。另外每周妈妈还会送她去学习朗诵、舞蹈和钢琴。但是津津如果一天上课超过八个小时就会不高兴,而且上得越久就会越不高兴。假设津津不会因......
  • 洛谷P5707 【深基2.例12】上学迟到(Python 3)
    题。审题:1.yyy要花十分钟垃圾分类!不要忘了在总分钟数上加102.如果时或分为个位数,则需要用0在前补位 思路:先把总共需要的分钟数算出来,然后求时和分。如果时大于8,那么再补上24,用来使时间符合格式。 关键点:1.补位:print('%02d'%m),具体看这篇2.注意当分钟数恰好为60倍数的......