B题——东二(差分、思维)

版权声明:转载记得标明出处哦~ https://blog.csdn.net/weixin_43890047/article/details/89018940

[CodeForces - 1041D]




中文意

你现在处于高度为h的地方,每秒y坐标会减少1,x坐标会增加1,而现在会有n个气流区[l,r],在每个气流区中,你的y坐标不会改变,你的x坐标每秒会增加1。(保证所给出的气流两两之间没有交集)现在你可以从x轴上的任意一点下落,现在问你最远的飞行路径。(即终点x坐标 减 起点x坐标的最6大值)

题目摘自:https://blog.csdn.net/qq_41289920/article/details/82962809

思路

一开始想到的是用一颗线段树维护区间最大值(区间-1最小),一棵树维护区间长度。但一般超过10^5以上的长度便不可使用线段树。
数据在10^5左右,猜测是nlogn算法。

这里提升一下思维。要有区间化点的思想,而差分就可以实现这个思想。同时差分可以用o(1)的时间算出区间M~N的值。处理差分的时间为o(n)。另:差分不支持修改,所以引出了树状数组概念。所以不修改区间的,用差分,修改区间的用树状数组

代码

#include<bits/stdc++.h>
using namespace std;
const int MAX = 2e5 + 5;
int n,h;
int b[MAX],c[MAX];
struct Node {
	int l,r;
} node[MAX];
int main()
{
	cin>>n>>h;
	for(int i = 1; i<=n; i++) scanf("%d%d",&node[i].l,&node[i].r);
	c[1] = 0;b[1] = node[1].r-node[1].l;
	///因为飞机优先从气流区开始飞行,前缀区间可视作0
	for(int i = 2; i<=n; i++) {
		b[i] = node[i].r - node[i].l;
		c[i] = node[i].l - node[i-1].r;
		b[i] += b[i-1];
		c[i] += c[i-1];
	}
	c[n+1] = INT_MAX;//这句貌似可以没有、、
	int maxx = -1,ans;
	for(int i = 1; i<=n; i++) {
        int pos = lower_bound(c+1,c+n+1,c[i]+h) - c;///lower_bound复杂度为logn
		ans = b[pos-1] - b[i-1];
		maxx = max(maxx,ans);
	}
	printf("%d\n",maxx+h);
	return 0 ;
}

猜你喜欢

转载自blog.csdn.net/weixin_43890047/article/details/89018940
今日推荐