codeforces818F Level Generation -- 三分

来源:互联网 发布:2016网络原创歌曲比赛 编辑:程序博客网 时间:2024/06/05 03:46

可以发现在k个点间连边,剩下nk个点向联通块中连一条边是最优的。
那么答案就是nk+min(nk,k(k1)2)
注意到nk是单调递减的,k(k1)2是单调递增的。
所以存在k0,使在[1,k0]min(nk,k(k1)2)是单调递增的,在[k0+1,n]min(nk,k(k1)2)是单调递减的。
那么在[1,k0]答案是单调递增的,在[k0+1,n]答案是单调递减的。
用三分就可以求出答案。

代码:

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;#define ll long longint i,j,k,n,m,p,Q;double Ans,l,r,m1,m2;inline double Min(double x,double y){    return x<y?x:y;}inline double Max(double x,double y){    return x<y?y:x;}inline double F(double x){    return n-x+Min(x*(x-1)/2,n-x);}int main(){    scanf("%d",&Q);    while(Q--){        scanf("%d",&n);        l=1;r=n;        while(r-l>0.1){            m1=(r-l)/3;m2=r-m1;m1+=l;            if(F(m1)>F(m2))r=m2;else l=m1;        }        l=(int)((l+r)/2);        printf("%.0lf\n",Max(F(l),F(l+1)));    }    return 0;}
原创粉丝点击