MAX Average Problem
Problem Description
Consider a simple sequence which only contains positive integers as a1, a2 ... an, and a number k. Define ave(i,j) as the average value of the sub sequence ai ... aj, i<=j. Let’s calculate max(ave(i,j)), 1<=i<=j-k+1<=n.
Input
There multiple test cases in the input, each test case contains two lines.
The first line has two integers, N and k (k<=N<=10^5).
The second line has N integers, a1, a2 ... an. All numbers are ranged in [1, 2000].
The first line has two integers, N and k (k<=N<=10^5).
The second line has N integers, a1, a2 ... an. All numbers are ranged in [1, 2000].
Output
For every test case, output one single line contains a real number, which is mentioned in the description, accurate to 0.01.
Sample Input
10 6 6 4 2 10 3 8 5 9 4 1
Sample Output
6.50
一道简单的斜率优化。用sum数组存放和,sum[i]为a[1]~a[i]的和,要求(sum[i]-sum[j])/(i-j)的最大值(i-j>=k)。
要用到输入挂,不然会超时。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
const int maxn=100005;
int sum[maxn];
int q[maxn];
namespace fastIO
{
#define BUF_SIZE 100000
bool IOerror=0;
inline char nc()
{
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if(p1==pend)
{
p1=buf;
pend=buf+fread(buf,1,BUF_SIZE,stdin);
if(pend==p1)
{
IOerror=1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch)
{
return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';
}
inline void read(int &x)
{
char ch;
while(blank(ch=nc()));
if(IOerror)
return ;
for(x=ch-'0'; (ch=nc())>='0'&&ch<='9'; x=x*10+ch-'0');
}
#undef BUF_SIZE
}
int main()
{
int n,k;
while(fastIO::read(n),!fastIO::IOerror)
//while(~scanf("%d%d",&n,&k))
{
fastIO::read(k);
sum[0]=0;
for(int i=1; i<=n; i++)
{
int a;
fastIO::read(a);
//a = GetInt();
sum[i]=sum[i-1]+a;
}
int head=0,tail=0;
double ans=0;
for(int i=k; i<=n; i++)
{
int j=i-k;
while(head+1<tail)//维护下凸性
{
int x1=j-q[tail-1];
int x2=j-q[tail-2];
int y1=sum[j]-sum[q[tail-1]];
int y2=sum[j]-sum[q[tail-2]];
if((ll)x1*y2>=(ll)y1*x2)
tail--;
else
break;
}
q[tail++]=j;
while(head+1<tail)//维护上凸性
{
int x1=q[head+1]-q[head];
int x2=i-q[head+1];
int y1=sum[q[head+1]]-sum[q[head]];
int y2=sum[i]-sum[q[head+1]];
if((ll)x1*y2>=(ll)y1*x2)
head++;
else
break;
}
double tmp=1.0*(sum[i] - sum[q[head]]) / (i - q[head]);
ans=max(ans,tmp);
}
printf("%.2f\n",ans);
}
return 0;
}