HDU6070(线段树)

来源:互联网 发布:linux on android 编辑:程序博客网 时间:2024/06/06 12:25

多校联合的题,之前竟然没有补,今天补上。
这个题的区间具有不可重叠性。
用线段树存放的是一个起点固定的 (不同数字数加l*k);
code:

#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<cmath>using namespace std;const int maxn=60010;const double eps=1e-5;struct node{    int l,r;    double add;    double mn;}tree[maxn<<2];void pushup(int index){    tree[index].mn=min(tree[index<<1].mn,tree[index<<1|1].mn);}void pushdown(int index){    tree[index<<1].mn+=tree[index].add;    tree[index<<1|1].mn+=tree[index].add;    tree[index<<1].add += tree[index].add;    tree[index<<1|1].add += tree[index].add;    tree[index].add=0.0;}void build(int l,int r,int index,double k){    tree[index].l=l;    tree[index].r=r;    tree[index].add=0.0;    if(l==r)    {        tree[index].mn=l*1.00*k;        //printf("%d     %f\n",l,tree[index].mn);        return ;    }    int mid=(l+r)>>1;    build(l,mid,index<<1,k);    build(mid+1,r,index<<1|1,k);    pushup(index);}void update(int l,int r,int index,double val){    if(l<=tree[index].l&&tree[index].r<=r)    {        tree[index].mn+=val;        tree[index].add+=val;        return ;    }    pushdown(index);    int mid=(tree[index].l+tree[index].r)>>1;    if(l<=mid)    {        update(l,r,index<<1,val);    }    if(r>mid)    {        update(l,r,(index<<1|1),val);    }    pushup(index);}double query(int l,int r,int index){    if(l<=tree[index].l&&tree[index].r<=r)    {        return tree[index].mn;    }    pushdown(index);    int mid=(tree[index].l+tree[index].r)>>1;    double Min=1210000.0;    if(l<=mid)    {        Min=min(query(l,r,index<<1),Min);    }    if(r>mid)    {        Min=min(query(l,r,index<<1|1),Min);    }    //cout<<Min<<endl;    return Min;}int pre[maxn];int a[maxn];int main(){    int _case;    scanf("%d",&_case);    while(_case--)    {        int n;        scanf("%d",&n);        memset(pre,0,sizeof(pre));        memset(a,0,sizeof(a));        for(int i=1;i<=n;i++)        {            scanf("%d",a+i);        }        double left=0.0;        double right=1.00;        while(right-left>eps)        {            memset(pre,0,sizeof(pre));            double mid=(right+left)/2.00;            build(1,n,1,mid);            bool flag=false;            for(int i=1;i<=n;i++)            {                int R=pre[a[i]];                /*printf("%d    %d\n",R+1,i);*/                update(R+1,i,1,1.00);                pre[a[i]]=i;                /*for(int j=1;j<=i;j++)                {                    cout<<j<<"           "<< query(j,j,1)<<endl;                }*/                if(query(1,i,1)<=mid+mid*(double)i)                {                    //printf("i=%d      you=%f\n",i,mid+mid*(double)i);                    flag=true;                    break;                }            }            if(flag)            {                right=mid;            }            else            {                left=mid;            }        }        printf("%.10f\n",(left+right)/2.00);    }    return 0;}
原创粉丝点击