#include<bits/stdc++.h>
using namespace std;
const int N =1e6+10;
struct node{
int val,node;
}a[N];
bool vis[N];
int n,m,num;
bool cmp(node a,node b){
return a.val<b.val;
}
template<class T,const int INF> class treeA{
struct node{
int sum,lazy;
}tree[INF<<1];
public:
void push_down(int s,int mid,int t,int p){
tree[p<<1].sum+=(mid-s+1)*tree[p].lazy,tree[p<<1|1].sum+=(t-mid)*tree[p].lazy;
tree[p<<1].lazy+=tree[p].lazy,tree[p<<1|1].lazy+=tree[p].lazy;
tree[p].lazy=0;
}
void update(int l,int r,int s,int t,int p,int val){
if(l<=s&&t<=r){
tree[p].sum+=(t-s+1)*val,tree[p].lazy+=val;
return ;
}
int mid=(s+t)>>1;
push_down(s,mid,t,p);
if(l<=mid) update(l,r,s,mid,p<<1,val);
if(r>mid) update(l,r,mid+1,t,p<<1|1,val);
tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;
}
int Query(int l,int r,int s,int t,int p){
if(l<=s&&t<=r) return tree[p].sum;
int mid=(s+t)>>1,ans=0;
push_down(s,mid,t,p);
if(l<=mid) ans+=Query(l,r,s,mid,p<<1);
if(r>mid) ans+=Query(l,r,mid+1,t,p<<1|1);
return ans;
}
};
treeA<int,N>TreeL,TreeR;
void Add(int dis){
if(vis[dis-1]==true&&vis[dis+1]==true){
int L=TreeL.Query(dis-1,dis-1,1,n,1),R=TreeR.Query(dis+1,dis+1,1,n,1);
if((R-L)%2==0) num++;
TreeL.update(dis+1,R,1,n,1,-(dis+1-L)),TreeR.update(L,dis-1,1,n,1,R-dis+1);
TreeL.update(dis,dis,1,n,1,L),TreeR.update(dis,dis,1,n,1,R);
}
else if(vis[dis-1]==true){
int L=TreeL.Query(dis-1,dis-1,1,n,1);
if((dis-1-L+1)%2==0) num++;
TreeR.update(L,dis-1,1,n,1,1),TreeL.update(dis,dis,1,n,1,L),TreeR.update(dis,dis,1,n,1,dis);
}
else if(vis[dis+1]==true){
int R=TreeR.Query(dis+1,dis+1,1,n,1);
if((R-dis-1+1)%2==0) num++;
TreeL.update(dis+1,R,1,n,1,-1),TreeL.update(dis,dis,1,n,1,dis),TreeR.update(dis,dis,1,n,1,R);
}
else
num++,TreeL.update(dis,dis,1,n,1,dis),TreeR.update(dis,dis,1,n,1,dis);
vis[dis]=true;
}
void Sub(int dis){
if(vis[dis-1]==true&&vis[dis+1]==true){
int L=TreeL.Query(dis-1,dis-1,1,n,1),R=TreeR.Query(dis+1,dis+1,1,n,1);
if((R-L+1)%2!=0) num--;
TreeL.update(dis+1,R,1,n,1,dis+1-L),TreeR.update(L,dis-1,1,n,1,-R+dis-1);
TreeL.update(dis,dis,1,n,1,-L),TreeR.update(dis,dis,1,n,1,-R);
}
else if(vis[dis-1]==true){
int L=TreeL.Query(dis-1,dis-1,1,n,1);
if((dis-L+1)%2!=0) num--;
TreeR.update(L,dis-1,1,n,1,-1),TreeL.update(dis,dis,1,n,1,-L),TreeR.update(dis,dis,1,n,1,-dis);
}
else if(vis[dis+1]==true){
int R=TreeR.Query(dis+1,dis+1,1,n,1);
if((R-dis+1)%2!=0) num--;
TreeL.update(dis+1,R,1,n,1,1),TreeL.update(dis,dis,1,n,1,-dis),TreeR.update(dis,dis,1,n,1,-R);
}
else
num--,TreeL.update(dis,dis,1,n,1,-dis),TreeR.update(dis,dis,1,n,1,-dis);
vis[dis]=false;
}
void Slove(){
int i=1,j=1,ans=INT_MAX;
while(i<=n&&j<=n){
while(num<m&&j<=n)
Add(a[j].node),j++;
if(j>n&&num<m) break;
// cout<<i<<" "<<j<<endl;
ans=min(ans,a[j-1].val-a[i].val);
Sub(a[i].node),i++;
}
cout<<ans<<endl;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i].val,a[i].node=i;
sort(a+1,a+n+1,cmp);
Slove();
}
是Add出了问题,但是没想出来是什么地方出了问题,答案小了。大阳历无法通过。