hdu6070 Dirt Ratio

来源:互联网 发布:淘宝会员中心 编辑:程序博客网 时间:2024/06/12 10:10

二分答案mid,检验是否存在一个区间满足size(l,r)/(r-l+1) mid,也就是size(l,r)+mid*lmid*(r+1)

#include<iostream>#include<stdio.h>#include<algorithm>#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;const int maxn=6e4+10;int tt,n,a[maxn],pos[maxn],add[maxn<<2];double L,R,MID,t,v[maxn<<2];void PushUp(int rt){    v[rt]=min(v[rt<<1],v[rt<<1|1]);}void PushDown(int rt){    if(add[rt]){        add[rt<<1]+=add[rt],v[rt<<1]+=add[rt];        add[rt<<1|1]+=add[rt],v[rt<<1|1]+=add[rt];        add[rt]=0;    }}void build(int l,int r,int rt){    v[rt]=MID*l,add[rt]=0;    if(l==r) return;    int mid=(l+r)/2;    build(lson),build(rson);}void updata(int l,int r,int rt,int LL,int RR){    //printf("%d %d %d %d\n",l,r,LL,RR);    if(LL<=l&&r<=RR){       add[rt]++,v[rt]++;       return;    }    PushDown(rt);    int mid=(l+r)/2;    if(LL<=mid) updata(lson,LL,RR);    if(RR>mid)  updata(rson,LL,RR);    PushUp(rt);}void query(int l,int r,int rt,int RR){    if(r<=RR){        t=min(t,v[rt]);        return;    }    PushDown(rt);    int mid=(l+r)/2;    query(lson,RR);    if(RR>mid) query(rson,RR);}int main(){    scanf("%d",&tt);    while(tt--){        scanf("%d",&n);        for(int i=1;i<=n;i++) scanf("%d",&a[i]);        L=0,R=1;        for(int c=0;c<20;c++){            MID=(L+R)/2;            build(1,n,1);            int i;            for(i=1;i<=n;i++) pos[i]=0;            for(i=1;i<=n;i++){                updata(1,n,1,pos[a[i]]+1,i);                t=1e9;                query(1,n,1,i);                if(t-MID*(i+1)<=0)  break;                pos[a[i]]=i;            }            if(i>n) L=MID;            else    R=MID;        }        printf("%.10f\n",(L+R)/2);    }}


原创粉丝点击