P10878 [JRKSJ R9] 在相思树下 III 题解
先说结论:先把操作一用完是最优的。
证明:
每次操作一都是在
而做一次操作二就相当于删去一个最大值,取出前
此时我们回过来看做
区间最值用线段树维护即可,时间复杂度
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,ans=LLONG_MAX;
int a[1000005],b[1000005];
struct node{
int l,r,sum1;
}tree[4000005];
void upd(int now){
tree[now].sum1=max(tree[now<<1].sum1,tree[now<<1|1].sum1);
}
void build(int now,int l,int r){
tree[now].l=l;
tree[now].r=r;
if(l==r){
tree[now].sum1=a[l];
return;
}
int mid=(l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
upd(now);
}
int search1(int now,int l,int r){
if(tree[now].l>=l&&tree[now].r<=r) return tree[now].sum1;
int mid=(tree[now].l+tree[now].r)>>1;
if(r<=mid) return search1(now<<1,l,r);
else if(l>mid) return search1(now<<1|1,l,r);
else return max(search1(now<<1,l,mid),search1(now<<1|1,mid+1,r));
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,1,n);
for(int i=1;i<=n-m;i++){
b[i]=search1(1,i,i+m);
ans=min(ans,b[i]);
}
printf("%lld",ans);
return 0;
}