这道题体面非常简单,如果你没有学过归并排序或者倍增,那就只能暴力拿分,这里不多说了,直接上AC代码。
#inlclude <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fiir(i,a,b) for(int i=a;i<=b;i++)
const int N=500005;
ll arr[N],temp[N],b[N],n,m,t,ans;
void merger(int l,int mid,int r){
int x=l,y=mid;
fiir(i,l,r) {
if(y>r||(x<mid&&temp[x]<=temp[y])){
b[i]=temp[x++];
}else{
b[i]=temp[y++];
}
}
}//归并排序
int check(int l,int mid,int r){
fiir(i,mid,r) temp[i]=arr[i];
sort(temp+mid,temp+r+1);
merger(l,mid,r);
ll kk=0;
for(int i=0;i<(r-l+1)/2&&i<m;i++) kk+=(ll)pow(b[r-i]-b[l+i],2);
if(kk>t) return 0;
else {
fiir(i,l,r) temp[i]=b[i];
return 1;
}
}//二分答案函数
void work(int l,int r){
temp[l]=arr[l];
int len=1;
while(r<=n){
if(!len){
len=1;
ans++;
l=++r;
temp[l]=arr[l];
}else if(r+len<=n&&check(l,r+1,r+len)){
r+=len;
len<<=1;
if(r==n) break;
}else{
len>>=1;
}
}
if(r==n) ans++;
// fiir(i,1,n) cout<<temp[i]<<" ";cout<<endl; 调试语句
}
int main()
{
ios::sync_with_stdio(false);
int k;
cin>>k;
while(k--){
ans=0;
cin>>n>>m>>t;
fiir(i,1,n) cin>>arr[i];
work(1,1);//调用
cout<<ans<<endl;
}
return 0;
}