luogu P5308 [COCI2019] Quiz
题面传送门
草不看题然后卡精度调了半天。
其实对于这种有\(k\)的东西就是考虑wqs二分吧。
然后显然这个有凸性。
所以直接斜率优化一下即可。
code:
#include <vector>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<algorithm>
#include<bitset>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define l(x) x<<1
#define r(x) x<<1|1
#define re register
#define ll long long
#define db long double
#define N 100000
#define eps (1e-14)
#define mod 1000000007
using namespace std;
int n,m,g[N+5],head,tail,q[N+5];db dp[N+5],l,r,mid;
I db slope(int x,int y){return (dp[y]-dp[x])/(y-x);}
I int check(db mid){
re int i,j;q[head=tail=0]=0;
for(i=1;i<=n;i++){
while(head<tail&&(slope(q[head],q[head+1])-(db)1/i>=eps||(fabs(slope(q[head],q[head+1])-(db)1/i)<=eps&&g[head]<g[head+1]))) head++;
j=q[head];dp[i]=dp[j]+(db)(i-j)/i+mid;g[i]=g[j]+1;
while(head<tail&&slope(q[tail-1],q[tail])-slope(q[tail-1],i)<=-eps||(fabs(slope(q[tail-1],q[tail])-slope(q[tail-1],i))<=eps&&g[tail]<g[i]))tail--;q[++tail]=i;
}
return g[n]>=m;
}
int main(){
freopen("1.in","r",stdin);
re int i;scanf("%d%d",&n,&m);l=-1e6;r=eps;
while(l+eps<r)mid=(l+r)/2.0,(check(mid)?r:l)=mid;check(r);printf("%.9Lf\n",dp[n]-r*m);
}

浙公网安备 33010602011771号