代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#define len 100010
using namespace std;
struct p
{
int num0,num1;
double rate;
};
p segment[len];
stack<p> st;
int a[len];
int main()
{
//freopen("1003.in","r",stdin);
//freopen("output.txt","w",stdout);
int T,n;
scanf("%d",&T);
while(T--)
{
while(!st.empty())
st.pop();
double ans=0;
scanf("%d",&n);
for(int i=1; i<=n; ++i)
scanf("%d",&a[i]);
int l=1,r=n;
//a[n+1]=1;
while(a[l]==0) l++;
while(a[r]==1) r--;
if(l>r)
ans=0.0;
else
{
int ct=0;
a[n+1]=3;//a[n+1]不能为0,不然计算a[i]==0的个数时可能会超出n的范围
for(int i=l; i<=r;)
{
int ct1=0,ct0=0;
while(a[i]==1)
{
ct1++;
i++;
}
while(a[i]==0)
{
ct0++;
i++;
}
segment[++ct].num0=ct0;
segment[ct].num1=ct1;
segment[ct].rate=1.0*ct1/(ct1+ct0);
}
//printf("hahha\n");
for(int i=1; i<=ct; ++i)
{
if(st.empty())
st.push(segment[i]);
else
{
p tmp = st.top();
if(segment[i].rate>=tmp.rate)
st.push(segment[i]);
else
{
while(1)
{
p t = st.top();
if(segment[i].rate<t.rate)
{
segment[i].num0+=t.num0;
segment[i].num1+=t.num1;
segment[i].rate=1.0*segment[i].num1/(segment[i].num1+segment[i].num0);
st.pop();
}
else if(segment[i].rate>=t.rate)
{
st.push(segment[i]);
break;
}
if(st.empty())
{
st.push(segment[i]);
break;
}
}
}
}
}
//printf("hahha\n");
ans=0.0;
while (!st.empty())
{
p tmp = st.top();
ans+=tmp.num0*tmp.rate*tmp.rate+tmp.num1*(1.0-tmp.rate)*(1.0-tmp.rate);
st.pop();
}
}
printf("%lf\n",ans);
}
return 0;
}