HDU 3193-Find the hotel (RMQ)

题目传送门
题意:找到所有满足(不存在比该酒店价格和距离都低的其他酒店)这样的酒店。

思路:即价格大于等于它的酒店不用考虑,只用考虑价格比他小的酒店当中是否距离最小的那个比它的距离大。若存在一个即该酒店满足。最后排序。

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
#define PII pair<int,int>
struct node{
	int p,d;
}a[N];
int b[N],dp[N][22],n;
void rmq(){ //预处理 rmq 
	for(int j=1;(1<<j)<=1e4;j++)
		for(int i=0;i+(1<<j)-1<=1e4;i++)
				dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
}
int fun(int l,int r){
	int len=r-l+1,k=0;
	while((1<<k)*2<len) k++;
	return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
bool cmp(PII a,PII b){
	return a.first==b.first?a.second<b.second:a.first<b.first;
}
int main(){
	while(~scanf("%d",&n)){
		memset(b,0x3f,sizeof b);//初始化 
	vector<PII >ans; 
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a[i].p,&a[i].d);
	 a[i].p++,a[i].d++;//存在值为0的情况加1便于处理 
	 b[a[i].p]=min(b[a[i].p],a[i].d);//记录相同价格的最小距离. 
	}
	  for(int i=0;i<N;i++)
			dp[i][0]=b[i];//初始化 
	rmq();
	for(int i=1;i<=n;i++)
	{
		int tmp=fun(0,a[i].p-1);//必须从0开始,若为1开始当 a[i].p=1时 a[i].p-1=0 则是L=1,R=0发生错误. 
		if(tmp>=a[i].d)//已知价格大于等于a[i].p的都满足条件,只要价格比它小的酒店距离都大于等于它就可以 
			ans.push_back({a[i].p,a[i].d}); 
	}
	printf("%d\n",ans.size());
	sort(ans.begin(),ans.end(),cmp);
	for(auto i:ans) printf("%d %d\n",i.first-1,i.second-1);//还原 
	}
	return 0;
}