首页 > 其他分享 >AT_nikkei2019_2_qual_d Shortest Path on a Line 题解

AT_nikkei2019_2_qual_d Shortest Path on a Line 题解

时间:2024-11-28 15:10:39浏览次数:8  
标签:ch log qual int 题解 复杂度 nikkei2019 dp

洛谷题目传送门

AT 题目传送门

博客园可能食用更佳

学校内部模拟赛出了这题,顺便来写下题解。

惊奇的发现题解区居然全是建图跑最短路,这怎么行,所以这一篇题解并没有跑任何最短路,而是使用了线段树优化 DP。

考虑将建边区间按右端点从小到大排序,每次以右端点为枚举编号,记作 \(x\) ,发现只会从 \([1,x-1]\) 中的点转移过来,故这样对区间排序后不会存在后效性,故可以开始规划 DP。

将区间从小到大排序后,记第 \(i\) 个区间为 \([L_i,R_i]\),\(dp_x\) 表示从点 \(1\) 出发到达点 \(x\) 的最短距离,则

\[dp_{R_i}= \begin{cases} \min_{j=L_i}^{R_i-1} dp_j+W_i &, R_i \geq 2 \\ 0 &, R_i=1 \\ \end{cases} \]

这样做的时间复杂度为 \(\mathcal O(mn+m \log m)\),那么就可以考虑优化一下复杂度

观察到 \(dp_{R_i}\) 需要快速查询 \(dp_{L_i,\dots,R_i-1}\) 的最小值,并且需要更新 \(dp_{R_i}\) 的值,故可以使用线段树区间查询最小值,单点修改即可,时间复杂度 \(O(m \log m + m \log n)\),其中 \(m \log m\) 为排序的时间复杂度,\(\log n\) 为线段树单次操作的时间复杂度,细节见代码

#include<bits/stdc++.h>
#define il inline
#define ls u<<1
#define rs u<<1|1
#define int long long//注意数据范围,需要开 long long
using namespace std;
const int N=3e5+5,INF=0x3f3f3f3f3f3f3f3f;
int n,m;
struct dat
{
	int L,R,W;
}a[N];
struct SGT//常规线段树操作
{
	int t[N<<2];
	void push_up(int u)
	{
		t[u]=min(t[ls],t[rs]);
	}
	void build(int u,int l,int r)
	{
		if(l==r) return t[u]=(l==1)?0:INF,void();//初始化 dp[1]=0
		int mid=(l+r)>>1;
		build(ls,l,mid);
		build(rs,mid+1,r);
		push_up(u);
	}
	void update(int u,int l,int r,int x,int k)
	{
		if(x==l&&r==x) return t[u]=k,void();//单点修改,故不用 push_down
		int mid=(l+r)>>1;
		if(x<=mid) update(ls,l,mid,x,k);
			else update(rs,mid+1,r,x,k);
		push_up(u);
	}
	int query(int u,int l,int r,int x,int y)
	{
		if(x<=l&&r<=y) return t[u];
		int mid=(l+r)>>1,res=INF;
		if(x<=mid) res=min(res,query(ls,l,mid,x,y));
		if(y>mid) res=min(res,query(rs,mid+1,r,x,y));
		return res;
	}
}T;
template <typename T>
il void read(T &x)
{
	x=0;int f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	x*=f;
}
signed main()
{
	read(n),read(m);
	T.build(1,1,n);//建树
	for(int i=1;i<=m;i++)
		read(a[i].L),read(a[i].R),read(a[i].W);
	sort(a+1,a+1+m,[](dat a,dat b){return a.R<b.R;});//按照右端点从小到大排序
	for(int i=1;i<=m;i++)
	{
		if(a[i].L==a[i].R) continue;//特判区间大小为 1 的情况
		int pre=T.query(1,1,n,a[i].L,a[i].R-1);//查询区间 [L_i,R_i-1] 的最小值
		int now=T.query(1,1,n,a[i].R,a[i].R);//查询 dp[R_i] 的值
		if(pre+a[i].W<now) T.update(1,1,n,a[i].R,pre+a[i].W);//若从前面转移过来更优,则修改
		//当然这里也可以直接在线段树上修改取 min 也行
	}
	int ans=T.query(1,1,n,n,n);//dp[n]
	printf("%lld",ans==INF?-1:ans);
	return 0;
}

标签:ch,log,qual,int,题解,复杂度,nikkei2019,dp
From: https://www.cnblogs.com/lunjiahao/p/18574275

相关文章

  • 【题解】洛谷P5906:【模板】回滚莫队&不删除莫队
    对于一些区间问题,虽然莫队好进行加操作,但并不好进行减操作,所以我们引出了回滚莫队。【模板】回滚莫队&不删除莫队发现我们并不总是知道什么时候取哪些值为最大值,尤其是删操作时,回滚莫队就是只用加操作实现的。我们对询问左端点所在的块排序,相同的话按照右排序,这样对于相同的左......
  • P10398 题解
    blog。博弈论。考虑使用AGC002E的方法分析:将\(a_i\)升序排列,然后画成下图状物。一次操作相当于消掉最下面的一行/最左边的一列,消完的人胜利。将这个问题转换为:你在左下角,每次可以往上面(上面是空的就走到右上)/右边走一步,谁先走到最后一列就赢了。于是可以写出\(O(\su......
  • [题解]CF1775E The Human Equation
    来个另类解。思路手玩一下样例,发现减法只会用在正数上,加法只会用在负数上,大概是因为如何在负数上用了减法或在正数上用了加法,都需要额外的次数去消掉。然后注意到在两个正数中间包这的所有负数可以直接缩成一个数,两个负数中间包着的所有正数也可以直接缩成一个数。那么现在的序......
  • FZOUTSY 题解
    题意简述给定一个长度为\(n\)的,由特定\(7\)种字符构成的字符串,有\(m\)次询问,每次询问需要求出编号在\([l,r]\)内的后缀中,有多少对后缀的最长公共前缀长度大于等于\(k\)。题目分析注意到在所有询问中,\(k\)的值是一样的,所以我们可以考虑求出给定字符串中以第\(i\)个......
  • [题解]P8867 [NOIP2022] 建造军营
    P8867[NOIP2022]建造军营只有B国袭破坏的道路是无向图的割边时,这张图才会变得不连通,所以我们进行边双缩点,最终形成一棵树,不妨令根节点为\(1\)。记\(E[u]\)为缩点后的\(u\)包含多少条原图上的边,\(V[u]\)为\(u\)包含多少个原图上的点,并定义\(s[u]\)表示子树\(u\)中的边数。那么......
  • 龙芯3A4000的linux系统下node14.17.5运行出现Floating point exception(浮点数异常)问
    因项目需要在龙芯下使用node14.17.5执行构建任务,在使用源码编译安装后,执行时出现Floatingpointexception(浮点数异常)问题。经调试发现,其是在使用openssl加载ECC相关证书时使用mips64汇编代码时导致的。在分析相关代码后,将deps下的openssl中的bn_div.c文件的16行进行修改,重新......
  • 2023ICPC 亚洲区域赛南京站 The 2nd Universal Cup 题解 更新至 7 题
    2023ICPC亚洲区域赛南京站The2ndUniversalCup题解更新至7题Preface住院了,在医院闲得无聊自己V了一场。这场复习赛,貌似半年前还是一年前打过一次,只过了4个题。今日来还愿了。但有些题还是不会做,真的唐。我会在代码一些有必要的地方加上注释,签到题可能一般就不会写了.......
  • python问题解决-外部模块明明安装了,却总是无法找到
    1现象代码中引入了cv2模块,这是一个图像识别模块。但运行时总提示找不到该模块。也按照要求安装了opencv-python等模块。还有其它的,如python-pptx模块,提示如下:Traceback(mostrecentcalllast):File"E:/python/wps/ppt_pic.py",line1,in<module>frompp......
  • [题解]P3629 [APIO2010] 巡逻
    P3629[APIO2010]巡逻\(k=1\)时,我们一定贪心选择直径\(d\)的两个端点建立道路,所以答案是\(2\times(n-1)-d+1\)。\(k=2\)时,两条新建的道路恰好形成\(2\)个环,我们通过手玩可以发现一个结论:\(1\)条边恰好被经过\(1\)次,当且仅当它恰好位于\(1\)个环上。\(1\)条边恰好被经过\(2\)......
  • ICPC2022济南站C. DFS Order 2 题解 回滚背包
    题目链接:https://www.luogu.com.cn/problem/P9669题目大意:给你一棵包含\(n\)个节点的有根树。节点编号从\(1\)到\(n\),节点\(1\)是根节点。从节点\(1\)出发对整棵树进行深度优先遍历,会得到很多不同的DFS序。解题思路:基本上和9981day大佬的题解一模一样差不多。......