zoukankan      html  css  js  c++  java
  • P5308 [COCI2019] Quiz

    纪念一下第二道 ( ext{wqs}) 二分题(我好弱啊),感觉题目很不错。

    题解

    按照 ( ext{wqs}) 二分的套路来,我们先不考虑轮数限制,大体思路上是需要倒序思考 (dp) 过程,即

    [f_i=max_{j<i}(f_j+frac{i-j}{i}) ]

    但是你发现这个 ( ext{dp})(O(n^2)) 的,本身就需要优化,发现可以斜率优化,即

    [f_{i}=f_j+frac{i-j}{i}\ f_icdot i=f_jcdot i+i-j\ (f_j+1)cdot i-f_icdot i=j\ ]

    我们维护点 ((f_j+1,j)) 的下凸包,并在转移的时候用斜率 (i) 去切它就可以了。

    我们在此时需要将 ( ext{wqs}) 二分结合进去,即在每一次转移中都需要减去我们当前二分到的斜率 (k) ,可以证明,这个斜率 (kin (0,1]) ,即

    [f_i=max_{j<i}(f_j+frac{i-j}{i}-k)\ (f_j+1-k)cdot i-f_{i}cdot i=j ]

    然后每一次二分后的 ( ext{dp}) 就维护点 ((f_j+1-k,j)) 的下凸包,并用斜率 (i) 去切它就可以了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define double long double
    const int N=1e5+5;
    int n,k;
    struct Point{double x,y;};
    struct Vector{double x,y;};
    Vector operator - (Point a,Point b){return (Vector){a.x-b.x,a.y-b.y};}
    double operator * (Vector a,Vector b){return a.x*b.y-a.y*b.x;}
    double res=0,f[N];int g[N];
    pair<Point,int> bag[N];
    pair<int,double> cal(double k){
    	int L=1,R=0;
    	memset(f,0,sizeof(f)),memset(g,0,sizeof(g));
    	f[1]=g[1]=1,bag[++R]=make_pair((Point){f[1]+1-k,1},g[1]);
    	for(int i=2;i<=n;++i){
    		while(R-L>0&&(bag[L+1].first-bag[L].first)*(Vector){1,1.0*i}>0) L++;
    		f[i]=bag[L].first.x-bag[L].first.y/i,g[i]=bag[L].second+1;
    		Point tmp=(Point){f[i]+1-k,1.0*i};
    		while(R-L>0&&(bag[R].first-bag[R-1].first)*(tmp-bag[R-1].first)<0) R--;
    		bag[++R]=make_pair(tmp,g[i]);
    	}
    	// for(int i=1;i<=n;++i) printf("%.9lf %d
    ",f[i],g[i]);
    	return make_pair(g[n],f[n]);
    }
    int main(){
    	cin>>n>>k;
    	double L=0,R=1;
    	while((R-L)>1e-16){
    		double Mid=(L+R)/2;pair<int,double> tmp=cal(Mid);
    		// printf("%.9lf %d %.9lf
    ",Mid,tmp.first,tmp.second);
    		if(tmp.first>=k) res=tmp.second+Mid*(k-1),L=Mid;
    		else R=Mid;
    	}
    	return printf("%.9Lf
    ",res),0;
    }
    
  • 相关阅读:
    glide引出恶心的git submodule
    恶心的hadoop集群
    恶心的sbt 超级慢--解决
    gradle 如何操作命令行
    TextView使用SpannableString设置复合文本(转)
    在gradle 中使用ant 执行 “命令行”(CMD)不出日志解决方案
    SQLServer常用运维SQL整理(转)
    github 拉取代码慢 的处理
    Docker部署Sentry
    下载网站的视频
  • 原文地址:https://www.cnblogs.com/Point-King/p/14564703.html
Copyright © 2011-2022 走看看