[USACO] Snow Boots

这篇博客分享了一种解决USACO Snow Boots问题的简单思路,采用排序和dis数组的方法,时间复杂度为O(nlog2n+q),适合初学者。博主通过排序和STL实现了这一过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

USACO Snow boots

洛谷链接
各位网友们用的都是并查集和双向链表这些高端操作,显然这对于我这种才学一年的初中蒟蒻来说是几乎想不到。这里献上一种特别无脑的解法。时间复杂度 O ( n l o g 2 n + q ) O(nlog_2n+q) O(nlog2n+q)(尽管它的常数很大)
我们对于每一块砖进行排序,dis数组来表示步长为i是最少要承受力为dis[i]的靴子,显然的只要知道每一个dis[i]的值,就可以 O ( 1 ) O(1) O(1)得回答每一个问题。剩下啦的就只有模拟这个思路了。由于我比较菜所以只会用stl来实现这个过程了。

#include<cstdio>
#include <map>
#include <set> 
#include <cmath>
#include <cstring>
#include <algorithm>
#define N 100005
using namespace std; 
inline char get(){
	const int TOP=1000000;
	static char T[TOP],*x=T,*y=T;
	return x==y&&(y=(x=T)+fread(T,1,TOP,stdin),x==y)?EOF:*x++;
}
inline int read (){
	register int num,sign=1;register char c;
	while (((c=get())<'0'||c>'9')&&c!='-');c=='-'?num=sign=0:num=c-48;
	while ((c=get())>='0'&&c<='9')num=(num<<3)+(num<<1)+(c-48);
	return sign?num:-num;
}
set<int>tr;//有哪些砖被计算
map<int,int>hash;//当前的可行步长,显然我们要的是最大的步长
struct node{
	int data,id;
	bool operator <(const node &x)const{
		return data<x.data;
	}
}A[N];
int n,q,x,y;
int dis[N];
set<int>::iterator l,r;
map<int,int>::iterator it;
int main(){
	memset(dis,0x7f,sizeof(dis));
	n=read();q=read();
	for(int i=1;i<=n;++i){A[i].data=read();A[i].id=i;}
	sort(A+2,A+n);
	hash[n-1]++;tr.insert(1);tr.insert(n);
	for(int i=2,j=2;i<n;i=j){
		while(A[j].data<=A[i].data&&j<n){
			l=r=tr.upper_bound(A[j].id);--l;
			if(!(--hash[*r-*l])){hash.erase(*r-*l);}
			hash[A[j].id-*l]++;hash[*r-A[j].id]++;
			tr.insert(A[j++].id);
		}
		it=hash.end();--it;
		dis[it->first]=min(dis[it->first],A[i].data);
	}
	dis[1]=A[n-1].data;dis[n-1]=0;
	for(int i=2;i<n;++i)dis[i]=min(dis[i],dis[i-1]);//步长更小的答案显然可以更新步长较大的答案
	while(q--){
		x=read();y=read();
		if(dis[y]<=x)printf("1\n");else printf("0\n");//O(1)的查询
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值