hdu 6070 Dirt Ratio 线段树+二分

时间:2023-03-09 09:00:02
hdu 6070 Dirt Ratio 线段树+二分

Dirt Ratio

Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Special Judge

Problem Description
In ACM/ICPC contest, the ''Dirt Ratio'' of a team is calculated in the following way. First let's ignore all the problems the team didn't pass, assume the team passed Xproblems during the contest, and submitted Y times for these problems, then the ''Dirt Ratio'' is measured as XY. If the ''Dirt Ratio'' of a team is too low, the team tends to cause more penalty, which is not a good performance.

hdu 6070 Dirt Ratio 线段树+二分
Picture from MyICPC

Little Q is a coach, he is now staring at the submission list of a team. You can assume all the problems occurred in the list was solved by the team during the contest. Little Q calculated the team's low ''Dirt Ratio'', felt very angry. He wants to have a talk with them. To make the problem more serious, he wants to choose a continuous subsequence of the list, and then calculate the ''Dirt Ratio'' just based on that subsequence.

Please write a program to find such subsequence having the lowest ''Dirt Ratio''.

Input
The first line of the input contains an integer T(1≤T≤15), denoting the number of test cases.

In each test case, there is an integer n(1≤n≤60000) in the first line, denoting the length of the submission list.

In the next line, there are n positive integers a1,a2,...,an(1≤ai≤n), denoting the problem ID of each submission.

Output
For each test case, print a single line containing a floating number, denoting the lowest ''Dirt Ratio''. The answer must be printed with an absolute error not greater than 10−4.
Sample Input
1
5
1 2 1 2 3
Sample Output
0.5000000000
Hint

For every problem, you can assume its final submission is accepted.

Source

官方题解:

hdu 6070 Dirt Ratio 线段树+二分

 

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
#include<stdlib.h>
#include<time.h>
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pi (4*atan(1.0))
#define bug(x) cout<<"bug"<<x<<endl;
#define eps 1e-4 const int N=6e4+,M=1e6+,inf=;
const LL INF=1e18+,mod=;
struct is
{
double minn[N<<];
int lazy[N<<];
void pushdown(int pos)
{
if(lazy[pos])
{
minn[pos<<]+=lazy[pos];
minn[pos<<|]+=lazy[pos];
lazy[pos<<|]+=lazy[pos];
lazy[pos<<]+=lazy[pos];
lazy[pos]=;
}
}
void build(int l,int r,int pos,double m)
{
lazy[pos]=;
if(l==r)
{
minn[pos]=m*l;
return;
}
int mid=(l+r)>>;
build(l,mid,pos<<,m);
build(mid+,r,pos<<|,m);
minn[pos]=min(minn[pos<<],minn[pos<<|]);
}
void update(int L,int R,int z,int l,int r,int pos)
{
if(L<=l&&r<=R)
{
minn[pos]+=z;
lazy[pos]+=z;
return;
}
pushdown(pos);
int mid=(l+r)>>;
if(L<=mid)update(L,R,z,l,mid,pos<<);
if(R>mid) update(L,R,z,mid+,r,pos<<|);
minn[pos]=min(minn[pos<<],minn[pos<<|]);
}
double query(int L,int R,int l,int r,int pos)
{
if(L<=l&&r<=R)return minn[pos];
pushdown(pos);
int mid=(l+r)>>;
double ans=;
if(L<=mid)ans=min(ans,query(L,R,l,mid,pos<<));
if(R>mid)ans=min(ans,query(L,R,mid+,r,pos<<|));
return ans;
}
}tree;
int n,pre[N],a[N];
int check(double x)
{
tree.build(,n,,x);
memset(pre,,sizeof(pre));
for(int i=;i<=n;i++)
{
tree.update(pre[a[i]]+,i,,,n,);
double p=tree.query(,i,,n,);
//cout<<i<<" "<<x<<" "<<p<<" "<<x*(i+1)<<endl;
if(p<=x*(i+))return ;
pre[a[i]]=i;
}
return ;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
double s=;
double e=,ans=-;
while(e-s>=eps)
{
double mid=(s+e)/;
if(check(mid))
{
ans=mid;
e=mid;
}
else s=mid;
}
printf("%f\n",ans);
}
return ;
}