QOJ.ac

QOJ

ID提交记录ID题目HackerOwner结果提交时间测评时间
#700#447908#8785. Fake Coin and Lying ScaleslichenghanlichenghanFailed.2024-06-19 22:06:242024-06-19 22:06:25

詳細信息

Extra Test:

Accepted
time: 0ms
memory: 4260kb

input:

1
1000000000 666666666

output:

28.31243658065795898438

result:

ok q=0 (1 test case)

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#447908#8785. Fake Coin and Lying ScaleslichenghanAC ✓200ms4240kbC++141.2kb2024-06-19 00:03:352024-06-19 00:03:36

answer

#include <bits/stdc++.h>
#define dbg(...) (fprintf(stderr,##__VA_ARGS__),fflush(stderr))
#define dputs(str) dbg(str "\n")
using namespace std;

double add_ln(double x,double y){
	if(x>y) swap(x,y);
	if(x-y>=30) return x;
	return y+log(exp(x-y)+1);
}

double fact(int x){
	return (x+0.5)*log(x);
}

double binom(int u,int d){
	if(d==0||d==u) return 0;
	return fact(u)-fact(d)-fact(u-d)-1;
}

long long n,k;
void solve(){
	scanf("%lld%lld",&n,&k);
	if(k==0){
		printf("%.20lf\n",n*log(3));
		return;
	}
	double bot=log(3*k+1);
	if(k>=n) return (void) printf("%.20lf\n",bot);
	double ans=log(3)*n+bot;
	double div=0;
	if(1.5*k>=n){
		div=log(3)*n;
	}else{
		for(int i=0;i<=40&&i<=k;i++){
			div=add_ln(div,binom(n,k-i)+log(2)*(k-i));
		}
	}
	ans-=div;
	// printf("%.20lf %.20lf\n",bot,ans);
	printf("%.20lf\n",max(bot,ans));
}

void test(){
	auto exact_binom=[&](int n,int k){
		double ans=0;
		for(int i=n;i>=n-k+1;i--) ans+=log(i);
		for(int i=k;i>=1;i--) ans-=log(i);
		return ans;
	};
	// const int n=40,k=20;
	const int n=1e6,k=5e5;
	printf("%+.4lf\n",exact_binom(n,k)-binom(n,k));
}

int main(){
	// test(); return 0;
	int tc;
	scanf("%d",&tc);
	while(tc--){
		solve();
	}
}