思路:
对于矩阵
W
W
W,给他硬二维构造肯定是不行,空间太大,那么我们肯定就要寻找其中的规律。
我们假定存在一个
h
h
h行,
k
k
k列的子矩阵使得答案最大,我们可以发现每个
a
i
a_i
ai只与第i行有关,而每个
b
i
b_i
bi
只与第i列有关,在模拟一下平均值:
( a 1 + a 2 + a 3 … … + a h ) ∗ k + ( b 1 + b 2 + … … + b k ) ∗ h h ∗ k \frac{(a_1+a_2+a_3……+a_h)*k+(b_1+b_2+……+b_k)*h}{h*k} h∗k(a1+a2+a3……+ah)∗k+(b1+b2+……+bk)∗h
即
( a 1 + a 2 + a 3 … … + a h ) h \frac{(a_1+a_2+a_3……+a_h)}{h} h(a1+a2+a3……+ah) + + + ( b 1 + b 2 + … … + b k ) k \frac{(b_1+b_2+……+b_k)}{k} k(b1+b2+……+bk)
那么我们就可以根据规律来做题啦,我们只需要找到数组a和数组b最大的平均值相加即可。
怎么找呢(赛场愣是不会)
当然我们可以二分答案,利用前缀和来维护,每次都让数组里的元素减去二分答案,在依次判断,如果存在大于等于
0
0
0的情况即为可行。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<sstream>
#include<queue>
#define fr for
#define pi 3.1415926535
#define me(a,b,c) memset(a,b,sizeof c)
#define cut cout
#define eps 0.00000001
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
typedef pair<int, int> pii;
const int N = 1e6 + 10;
double a[N];
double b[N];
double sum[N];
bool check(double f[], double s,int len,int re) {
sum[0] = 0;
for (int i = 1; i <= len; i++)sum[i] = sum[i - 1] + f[i] - s;
double p = 0x3f3f3f3f;
for (int i = re; i <= len; i++) {
p = min(p, sum[i - re]);//保证区间长度至少为re
if (sum[i] - p >= 0)return true;
}
return false;
}
int main() {
int n, m, x, y;
cin >> n >> m >> x >> y;
fr(int i = 1; i <= n; i++)cin >> a[i];
fr(int i = 1; i <= m; i++)cin >> b[i];
double l = 0, r = 1e5 + 10;
while (r - l > eps) {
double mid = (l + r) / 2;
if (check(a,mid,n,x))l = mid;
else r = mid;
}
double ans = l;
l = 0, r = 1e5 + 10;
while (r - l > eps)
{
double mid = (l + r) / 2;
if (check(b, mid,m,y))l = mid;
else r = mid;
}
ans += l;
printf("%.10lf\n", ans);
}