题解:P1638 逛画展
HaneDaniko · · 题解
主要思路:线段树
我们对
我们从小到大遍历所有的画,不断更新树上节点的值。假设我们遍历到当前点满足了答案,可以证明,当所有画的位置都距离当前点最近时,答案是最优的。
这样做还有一个好处:我们可以直接求出这个最优的答案。每次更新节点之后,我们对树上全部节点取一个最小值,假如这个最小值是
注意到,因为我们只需要查询根节点的最值,因此这个线段树是
代码
#include<bits/stdc++.h>
using namespace std;
int n,k;
int a[1000001];
struct tree{
int l,r;
int min;
}t[8001];
#define tol (id*2)
#define tor (id*2+1)
#define mid(l,r) mid=((l)+(r))/2
void build(int id,int l,int r){
t[id].l=l;t[id].r=r;t[id].min=0;
if(l==r){
return;
}
int mid(l,r);
build(tol,l,mid);
build(tor,mid+1,r);
}
void change(int id,int p,int val){
if(t[id].l==t[id].r){
t[id].min=val;return;
}
if(p<=t[tol].r) change(tol,p,val);
else change(tor,p,val);
t[id].min=min(t[tol].min,t[tor].min);
}
int ask(){
return t[1].min;
}
int main(){
int cnt=0;int l=0,r=0;
ios::sync_with_stdio(false);
cin>>n>>k;int x,y;
for(int i=1;i<=n;++i){
cin>>a[i];
}
build(1,1,k);
int ans=0x7fffffff;
for(int i=1;i<=n;++i){
change(1,a[i],i);
if(ask()!=0){
if(ans>i-ask()){
l=ask();r=i;
ans=r-l;
}
}
}
cout<<l<<" "<<r;
}