gym/101741D. Elevator

https://codeforces.com/gym/101741/problem/D

首先有简单的dp,dp[i]=min{max{dp[j-1],t[i]}+2*max{a[j]--a[i]}} ,然后发现这个怎么都要n^2,好像没撒能维护的数据结构

然后要观察出一个性质,就是后面如果有比a[i]大的,当前这个一定跟后面那个更大的一起走,这个性质其实看下面化简了的dp式子也能看出来,这个性质有点像18桂林的Ahttps://blog.csdn.net/liufengwei1/article/details/109756288

然后我们合并一下,使得a[i]严格递减,dp就变成了dp[i]=min{max{dp[j-1],t[i]},2*a[j]}

那么对j二分一下,dp[j-1]<=t[i]的,dp[i]=t[i]+2*a[j],否则dp[i]=dp[j-1]+2*a[j],前面那个由于是a递减的,所以最小的a[j]就是边界上的,右边这个用线段树维护一下就行了

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
 
const int maxl=3e5+10;
const ll inf=1ll<<60;
 
int n,m,cnt,tot;ll ans;
int ctin[maxl],ca[maxl],b[maxl],sufmx[maxl];
ll tin[maxl],a[maxl],dp[maxl];
struct node
{
	int l,r;
	ll mi;
}tr[maxl*4];
 
inline void build(int k,int l,int r)
{
	tr[k].l=l;tr[k].r=r;tr[k].mi=0;
	if(l==r)
		return;
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
}
 
inline void prework()
{
	for(int i=1;i<=n;i++)
		scanf("%d%d",&ctin[i],&ca[i]);
	sufmx[n]=ca[n];
	for(int i=n-1;i>=1;i--)
		sufmx[i]=max(sufmx[i+1],ca[i]);
	cnt=0;sufmx[n+1]=0;
	for(int i=1;i<=n;i++)
	{
		if(sufmx[i+1]>=ca[i])
			continue;
		b[++cnt]=i;
		tin[cnt]=ctin[i];a[cnt]=ca[i];
	}
	n=cnt;
	build(1,1,n);
}
 
inline void upd(int k,int l,ll x)
{
	if(tr[k].l==tr[k].r)
	{
		tr[k].mi=x;
		return;
	}
	int mid=(tr[k].l+tr[k].r)>>1;
	if(l<=mid)
		upd(k<<1,l,x);
	else
		upd(k<<1|1,l,x);
	tr[k].mi=min(tr[k<<1].mi,tr[k<<1|1].mi);
}
 
inline ll getmi(int k,int l,int r)
{
	if(tr[k].l==l && tr[k].r==r)
		return tr[k].mi;
	int mid=(tr[k].l+tr[k].r)>>1;
	if(r<=mid)
		return getmi(k<<1,l,r);
	else if(l>mid)
		return getmi(k<<1|1,l,r);
	else
		return min(getmi(k<<1,l,mid),getmi(k<<1|1,mid+1,r));
}
 
inline void mainwork()
{
	for(int i=1;i<=n;i++)
	{
		upd(1,i,dp[i-1]+2*a[i]);
		if(dp[i-1]<=tin[i])
			dp[i]=tin[i]+2*a[i];
		else
		{
			int l=0;
			for(int j=20;j>=0;j--)
			if(l+(1<<j)<=i-1 && dp[l+(1<<j)]<=tin[i])
				l+=(1<<j);
			dp[i]=tin[i]+2*a[l+1];
			dp[i]=min(dp[i],getmi(1,l+2,i));
		}
	}
}
 
inline void print()
{
	printf("%lld\n",dp[n]);
}
 
int main()
{
	while(~scanf("%d",&n))
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

您提供的链接是Codeforces的一个问题,问题编号为104377。Codeforces是一个知名的在线编程竞赛平台,经常举办各种编程比赛和训练。Gym是Codeforces的一个扩展包,用于组织私人比赛和训练。您提供的链接指向了一个问题的页面,但具体的问题内容和描述无法通过链接获取。如果您有具体的问题或需要了解关于Codeforces Gym的更多信息,请提供更详细的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [http://codeforces.com/gym/100623/attachments E题](https://blog.csdn.net/weixin_30820077/article/details/99723867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [http://codeforces.com/gym/100623/attachments H题](https://blog.csdn.net/weixin_38166726/article/details/99723856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CodeforcesPP:Codeforces扩展包](https://download.csdn.net/download/weixin_42101164/18409501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值