问你所有区间中平均数第k大的那个平均数.
首先想到二分,但是怎么检查呢
sum[r]-sum[l]/(r-l) <= x
=>
sum[r]-r*x<=sum[l]-l*x
这样就可以树状数组统计.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <set>
#ifdef noob
#define debug(x) std::cerr << #x << " = " << (x) << std::endl
#else
#define debug(...)
#endif
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 17;
const int MOD = 1e9 + 7;
LL bit[MAXN],n,k,a[MAXN],sum[MAXN];
void add(int p,int x)
{
while(p<=n)
{
bit[p] += x;
p += p&-p;
}
}
LL query(int p)
{
LL ret = 0;
while(p>0)
{
ret += bit[p];
p -= p&-p;
}
return ret;
}
bool judge(double x)
{
debug(x);
memset(bit, 0, sizeof(bit));
LL tmp = 0;
vector<int > aft(n+10);
vector<double > bef;
bef.push_back(0);
for (int i = 1; i <= n; ++i)
{
bef.push_back(-x*i+sum[i]);
debug(-x*i+sum[i]);
}
sort(bef.begin(), bef.end());
// for(auto i: bef)
// debug(i);
add(lower_bound(bef.begin(), bef.end(), 0)-bef.begin()+1,1);
for (int i = 1; i <= n; ++i)
{
aft[i] = lower_bound(bef.begin(), bef.end(), -x*i+sum[i])-bef.begin()+1;
debug(aft[i]);
tmp += 1LL*(i-1-query(aft[i]));
debug(i-1-query(aft[i]));
add(aft[i],1);
}
debug(tmp);
if(tmp>((n*(n-1))/2-k))
return false;
else
return true;
}
int main()
{
#ifdef noob
freopen("Input.txt","r", stdin);
freopen("Output.txt", "w", stdout);
#endif
cin>>n>>k;
sum[0] = 0;
for (int i = 0; i < n; ++i)
{
cin>>a[i+1];
sum[i+1] = sum[i]+a[i+1];
}
double l = 0,r = 100000+3;
for (int i = 0; i < 100; ++i)
{
double mid = (l+r)/2;
if(judge(mid))
{
// debug(mid);
l = mid;
}
else
{
// debug(mid);
r = mid;
}
}
cout<<l<<endl;
return 0;
}