原题链接
https://ac.nowcoder.com/acm/contest/11255/J
题目大意
给定一个
n
×
m
(
1
≤
n
,
m
≤
1
0
5
)
n\times m(1\leq n,m\leq 10^5)
n×m(1≤n,m≤105)的矩阵
W
W
W,矩阵上的元素满足
W
i
,
j
=
a
i
+
b
j
W_{i,j}=a_i+b_j
Wi,j=ai+bj,其中
a
i
,
b
j
(
1
≤
a
i
,
b
j
≤
1
0
5
)
a_i,b_j(1\leq a_i,b_j\leq 10^5)
ai,bj(1≤ai,bj≤105)已知。
求其平均值最大的连续子矩阵,且满足第一维度至少为
x
(
1
≤
x
≤
n
)
x(1\leq x\leq n)
x(1≤x≤n),第二维度至少为
y
(
1
≤
y
≤
n
)
y(1\leq y\leq n)
y(1≤y≤n)。
题解
根据
W
i
,
j
W_{i,j}
Wi,j的生成方式我们可知,
W
i
,
1...
m
=
a
i
+
b
1...
m
W_{i,1...m}=a_i+b_{1...m}
Wi,1...m=ai+b1...m,
W
1...
n
,
j
=
a
1...
n
+
b
j
W_{1...n,j}=a_{1...n}+b_j
W1...n,j=a1...n+bj。
所以我们只需二分寻找
a
a
a数组中长度至少为x的最大连续区间的平均值、
b
b
b数组中长度至少为y的最大连续区间的平均值,并相加即可。
参考代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
const double eps=1e-8;
int n,m,x,y;
int v[N];
double e[N];
double w(int k,int sz)
{
double l=0.0,r=100001.0;
for(int i=1;i<=k;i++)scanf("%d",&v[i]);
while(r-l>eps)
{
double mid=(l+r)/2.0,num,p=0.0;
for(int i=1;i<=sz;i++)e[i]=e[i-1]+v[i]-mid;
num=e[sz];
for(int i=sz+1;i<=k;i++)
{
p=min(p,e[i-sz]);
e[i]=e[i-1]+v[i]-mid;
num=max(num,e[i]-p);
}
if(num>=0)l=mid;
else r=mid;
}
return r;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&x,&y);
printf("%.10lf\n",w(n,x)+w(m,y));
}