http://acm.hdu.edu.cn/showproblem.php?pid=6070
题解
首先不难看出错误率是单调的,那么我们可以直接二分答案x,某个区间的错误率=区间数的种类cnt/区间长度r-l+1,变成:cnt+l*x
1 #define dbg(x) cout<<#x<<" = "<< (x)<< endl
2 #define IO std::ios::sync_with_stdio(0);
3 #include
4 #define iter ::iterator
5 using namespace std;
6 typedef long long ll;
7 typedef pairP;
8 #define pb push_back
9 #define se second
10 #define fi first
11 #define rs o<<1|1
12 #define ls o<<1
13 #define inf 0x3f3f3f3f
14 const int N=6e4+5;
15 int T,n;
16 int a[N],add[N*4];
17 double minv[N*4],x;
18 void push(int o){
19 minv[o]=min(minv[ls],minv[rs]);
20 }
21 void down(int o){
22 if(add[o]){
23 minv[ls]+=add[o];
24 minv[rs]+=add[o];
25 add[ls]+=add[o];
26 add[rs]+=add[o];
27 add[o]=0;
28 }
29 }
30 void build(int o,int l,int r){
31 add[o]=0;
32 if(l==r){
33 minv[o]=x*l;
34 return;
35 }
36 int m=(l+r)/2;
37 build(ls,l,m);
38 build(rs,m+1,r);
39 push(o);
40 }
41 void up(int o,int l,int r,int ql,int qr,int v){
42 if(l>=ql&&r<=qr){
43 add[o]+=v;
44 minv[o]+=v;
45 return;
46 }
47 down(o);
48 int m=(l+r)/2;
49 if(ql<=m)up(ls,l,m,ql,qr,v);
50 if(qr>m)up(rs,m+1,r,ql,qr,v);
51 push(o);
52 }
53 double qu(int o,int l,int r,int ql,int qr){
54 if(l>=ql&&r<=qr){
55 return minv[o];
56 }
57 int m=(l+r)/2;
58 double res=1e9;
59 down(o);
60 if(ql<=m)res=min(res,qu(ls,l,m,ql,qr));
61 if(qr>m)res=min(res,qu(rs,m+1,r,ql,qr));
62 return res;
63 }
64 int pre[N],le[N];
65 int check(){
66 build(1,1,n);
67 for(int i=1;i<=n;i++){
68 up(1,1,n,le[i]+1,i,1);
69 double res=qu(1,1,n,1,i);
70 if(res<=x*(i+1))return 1;
71 }
72 return 0;
73 }
74 int main(){
75 scanf("%d",&T);
76 while(T--){
77 scanf("%d",&n);
78 memset(le,0,sizeof(le));
79 memset(pre,0,sizeof(pre));
80 for(int i=1;i<=n;i++){
81 scanf("%d",&a[i]);
82 le[i]=pre[a[i]];
83 pre[a[i]]=i;
84 }
85 double l=0,r=1;
86 for(int i=1;i<=30;i++){
87 double m=(l+r)/2;
88 x=m;
89 if(check())r=m;
90 else l=m;
91 }
92 printf("%.9lf\n",x);
93 }
94 }