这题真是OI题?

T1:
20180613小测
就是给你一个不明觉厉的递推式然后计算东西啦。
首先我们能用long double写一个暴力,发现前几项越来越小,后几项越来越大,明显不对......
考虑为什么,因为计算机中的浮点数是有误差的,这样推的话,误差会被放大到n!级,直接GG!
应该怎样做?手玩了半天发现没什么通项公式,难道写一个带压位FFT能做除法的高精度小数类?然后再求一个3w位有效数字的e?人干事,弃坑弃坑......
于是写了10分暴力。由于没有删调试语句爆了零。
考虑正解怎么做(抄题解?):
首先我们有一个结论:
20180613小测
于是我们可以这样从后向前递推f(n),不存在精度误差。
20180613小测
(SDFZ某神仙:我观察到这东西绝对值越来越小,于是可以令f(1e5)=0,然后逆推f(n),于是就这样AC了此题)
如何证明这个结论?
首先我们先构造一个积分:
20180613小测
考虑如何计算?首先我们有:
20180613小测
我们令u,v等于如下值,则有:
20180613小测
我们钦定g,h为如下意义:
20180613小测
则有:
20180613小测
没错,这东西就是f了。
此外我们有:
20180613小测
两边同时求积分,可得:
20180613小测
也就是:
20180613小测
于是我们就证明完了......
(话说这真不是数竞巨佬的来强行出题了?)
考场爆零代码:

 1 #include<cstdio>
 2 #include<cmath>
 3 typedef long double ldb;
 4 const int maxn=1e4+1e2;
 5 const ldb e = exp(1);
 6 
 7 ldb f[maxn];
 8 
 9 int main() {
10     static int n;
11     scanf("%d",&n) , *f = 1 - 1 / e;
12     for(int i=1;i<=n;i++) f[i] = 1 - i * f[i-1];
13     printf("%0.4Lf\n",120/e-44);
14     printf("%0.4Lf\n",f[n]);
15     return 0;
16 }
View Code

相关文章: