• 2017 Multi-University Training Contest 4 hdu 6070


    HDU - 6070 

    题意:提交了n次题目,每个题目都是最后一次提交的时候AC的,现在求一个区间,这个区间的AC率是最低的(只考虑这个区间内的题目,同样区间内最后交的一遍是AC的),求最低的AC率

    思路: 线段树+二分;AC率=提交次数/题目数目,即区间长度/题目种类,siz[l,r]/(r-l+1)=p(siz[l,r]表示l r区间内的不同题目的个数,p表示AC率), 把式子做一下调整,siz[l,r]+p*l=p(r+1),二分p(0-1)用线段树维护siz[l,r]+l*p 的最小值,然后枚举r,每次更新,因为l交给线段树维护了,所以不需要考虑l的位置,题解真是666,重新认识了线段树,感谢飞哥的大力帮助@jhz033,不然我还不知道线段树维护的是什么东西,这个题式子好写,但是思路难想,代码也好拍,但是余味还可以回味一年,这种思想还是值得去品味的,这波不亏

    AC代码:

    #include "iostream"
    #include "string.h"
    #include "stack"
    #include "queue"
    #include "string"
    #include "vector"
    #include "set"
    #include "map"
    #include "algorithm"
    #include "stdio.h"
    #include "math.h"
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ll long long
    #define endl ("
    ")
    #define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
    #define mem(a,x) memset(a,x,sizeof(a))
    #define mp(x,y) make_pair(x,y)
    #define pb(x) push_back(x)
    #define ft (frist)
    #define sd (second)
    #define lrt (rt<<1)
    #define rrt (rt<<1|1)
    using namespace std;
    const long long INF = 1e18+1LL;
    const int inf = 1e9+1e8;
    const double eps=1e-4;
    const int N=6e4+100;
    const ll mod=1e9+7;
    
    int n,a[N];
    double MID;
    struct TREE{
        int lazy[N<<2];
        double mi[N<<2];
        void push_up(int rt){
            mi[rt]=min(mi[lrt], mi[rrt]);
        }
        void push_down(int rt){
            mi[lrt]+=lazy[rt];
            mi[rrt]+=lazy[rt];
            lazy[lrt]+=lazy[rt];
            lazy[rrt]+=lazy[rt];
            lazy[rt]=0;
        }
        void creat(int rt, int l, int r){
            lazy[rt]=0;
            if(l==r){
                mi[rt]=MID*l;
                return;
            }
            int mid=l+r>>1;
            creat(lrt, l, mid);
            creat(rrt, mid+1, r);
            push_up(rt);
        }
        void update(int rt, int l, int r, int L, int R){
            if(L<=l && R>=r){
                mi[rt]+=1;
                lazy[rt]+=1;
                return;
            }
            if(lazy[rt]!=0) push_down(rt);
            int mid=l+r>>1;
            if(L<=mid) update(lrt, l, mid, L, R);
            if(R>mid) update(rrt, mid+1, r, L, R);
            push_up(rt);
        }
        double query(int rt, int l, int r, int L, int R){
            if(L<=l && R>=r){
                return mi[rt];
            }
            if(lazy[rt]!=0) push_down(rt);
            int mid=l+r>>1;
            double ans=99999999999;
            if(L<=mid) ans=min(ans,query(lrt, l, mid, L, R));
            if(R>mid) ans=min(ans,query(rrt, mid+1, r, L, R));
            return ans;
        }
    }tree;
    
    bool check(){
        int pre[N]; mem(pre,0);
        tree.creat(1,1,n);
        for(int i=1; i<=n; ++i){
            tree.update(1, 1, n, pre[a[i]]+1, i);
            double f=tree.query(1,1,n,1,i);
            if(f<=MID*(i+1)) return 1;
            pre[a[i]]=i;
        }
        return 0;
    }
    int main(){
        ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
        int T;
        cin>>T;
        while(T--){
            cin>>n;
            for(int i=1; i<=n; ++i){
                cin>>a[i];
            }
            double l=0, r=1, ans=0;
            while(r-l>=eps){
                MID=(l+r)/2;
                if(check()){
                    ans=MID;
                    r=MID;
                }
                else l=MID;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    php与nginx配置,不能运行php程序
    奇葩php之数组
    奇葩之mysql
    for语法研究
    php short tag不显示排查
    奇葩之mysql【三】我只想获得一个自增Id,我容易吗我
    男女不同
    Restart explorer
    iOS面试贴士
    phpmyadmin万能登陆密码
  • 原文地址:https://www.cnblogs.com/max88888888/p/7302478.html
Copyright © 2020-2023  润新知