zoukankan      html  css  js  c++  java
  • Manthan, Codefest 16 E. Startup Funding ST表 二分 数学

    E. Startup Funding

    题目连接:

    http://codeforces.com/contest/633/problem/E

    Description

    An e-commerce startup pitches to the investors to get funding. They have been functional for n weeks now and also have a website!

    For each week they know the number of unique visitors during this week vi and the revenue ci. To evaluate the potential of the startup at some range of weeks from l to r inclusive investors use the minimum among the maximum number of visitors multiplied by 100 and the minimum revenue during this period, that is:

    The truth is that investors have no idea how to efficiently evaluate the startup, so they are going to pick some k random distinct weeks li and give them to managers of the startup. For each li they should pick some ri ≥ li and report maximum number of visitors and minimum revenue during this period.

    Then, investors will calculate the potential of the startup for each of these ranges and take minimum value of p(li, ri) as the total evaluation grade of the startup. Assuming that managers of the startup always report the optimal values of ri for some particular li, i.e., the value such that the resulting grade of the startup is maximized, what is the expected resulting grade of the startup?

    Input

    The first line of the input contains two integers n and k (1 ≤ k ≤ n ≤ 1 000 000).

    The second line contains n integers vi (1 ≤ vi ≤ 107) — the number of unique visitors during each week.

    The third line contains n integers ci (1 ≤ ci ≤ 107) —the revenue for each week.

    Output

    Print a single real value — the expected grade of the startup. Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

    Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .

    Sample Input

    3 2
    3 2 1
    300 200 300

    Sample Output

    133.3333333

    Hint

    题意

    有n个人,每个人有两个权值,v[i]和c[i]

    然后有一个函数p(l,r) = min(100*max(v[l..r]),min(c[l..r]))

    对于每一个i,你需要找到一个最大的p(i,ri)

    然后现在从n个p(i,ri)中选取k个,然后再从这k个中选取其中最小的

    问你选出来的数的期望是多少

    题解:

    首先处理第一个问题,对于每一个i如何确定一个最大的p(i,ri)

    我们看到v[l..r]是一个单调递增的函数,c[l..r]是一个单调递减的函数

    这两个函数取min,肯定是个单峰函数,我们直接二分找到峰值,那么我就就得到了p(i,ri)了

    然后我们再处理第二个问题,期望怎么算

    我们首先把所有的p(i,ri)从小到大排序,那么最后选出第i个数的概率是C(n-i,k-1)/c(n,k)

    从n-i个数里面选择k-1个出来,这是贡献这个的概率

    总共有c(n,k)种选择

    这个组合数是可以递推的,然后我们搞一搞就出来了咯。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6+5;
    struct RMQMAX{
        const static int RMQ_size = maxn;
    	int n;
    	int ArrayMax[RMQ_size][21];
    
    	void build_rmq(){
    		for(int j = 1 ; (1<<j) <= n ; ++ j)
    			for(int i = 0 ; i + (1<<j) - 1 < n ; ++ i){
    				ArrayMax[i][j]=max(ArrayMax[i][j-1],ArrayMax[i+(1<<(j-1))][j-1]);
    			}
    	}
    
    	int QueryMax(int L,int R){
    		int k = 0;
    		while( (1<<(k+1)) <= R-L+1) k ++ ;
    		return max(ArrayMax[L][k],ArrayMax[R-(1<<k)+1][k]);
    	}
    
    	void init(int * a,int n){
    		this->n = n ;
    		for(int i = 0 ; i < n ; ++ i) ArrayMax[i][0] = a[i];
    		build_rmq();
    	}
    
    }S1;
    struct RMQMIN{
    	const static int RMQ_size = maxn;
    	int n;
    	int ArrayMin[RMQ_size][21];
    
    	void build_rmq(){
    		for(int j = 1 ; (1<<j) <= n ; ++ j)
    			for(int i = 0 ; i + (1<<j) - 1 < n ; ++ i){
    				ArrayMin[i][j]=min(ArrayMin[i][j-1],ArrayMin[i+(1<<(j-1))][j-1]);
    			}
    	}
    
    	int QueryMin(int L,int R){
    		int k = 0;
    		while( (1<<(k+1)) <= R-L+1) k ++ ;
    		return min(ArrayMin[L][k],ArrayMin[R-(1<<k)+1][k]);
    	}
    
    	void init(int * a,int n){
    		this->n = n ;
    		for(int i = 0 ; i < n ; ++ i) ArrayMin[i][0] = a[i];
    		build_rmq();
    	}
    
    }S2;
    int n,k,v[maxn],c[maxn],val[maxn],a[maxn];
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=0;i<n;i++)
            scanf("%d",&v[i]);
        for(int i=0;i<n;i++)
            scanf("%d",&c[i]);
        S1.init(v,n+1);
        S2.init(c,n+1);
        for(int i=0;i<n;i++)
        {
            int l=i,r=n-1,nxt=i;
            while(l<=r)
            {
                int mid=(l+r)/2;
                if(S1.QueryMax(i,mid)*100<S2.QueryMin(i,mid))l=mid+1,nxt=mid;
                else r=mid-1;
            }
            int L = min(S1.QueryMax(i,nxt)*100,S2.QueryMin(i,nxt));
            int R = min(S1.QueryMax(i,nxt+1)*100,S2.QueryMin(i,nxt+1));
            val[i]=max(L,R);
        }
        sort(val,val+n);
        double p = 1.0*k/(1.0*n);
        double ans = p*val[0];
        for(int i=1;n>=i+k;i++)
        {
            p = p*(1.0*n-i-k+1)/(1.0*n-i);
            ans+=p*val[i];
        }
        printf("%.12f
    ",ans);
    	return 0;
    }
  • 相关阅读:
    计算机科学导论第二周学习总结
    计算机科学概论2,3章小结
    2019—2020第一学期20202430王凯欣《网空概论》第四第五章学习小结
    2020—2021年第一学期20202430王凯欣《计算机科学概论》第一次笔记
    2020-2021第一学期20202410《计算机科学概论》第二次学习总结
    2020-2021第一学期20202410《计算机科学概论》第一次学习总结
    网页登录上网账号
    python从socket做个websocket的聊天室server
    windows下python 编码问题
    由css属性:vertial-align想到的。。
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5224552.html
Copyright © 2011-2022 走看看