博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 10236 The Fibonacci Primes
阅读量:4912 次
发布时间:2019-06-11

本文共 2619 字,大约阅读时间需要 8 分钟。

UVA_10236

    这个题目AC得太辛苦了,也再一次加深了对浮点数误差的理解,库函数能不调还是最好别调……其实后来感觉就像UVA论坛上一个人说的,AC这个题有两个准则,第一个是要用long double,第二个是不要相信fmod、sqrt、pow等这些库函数,它们都会带来精度上的问题。

    下面回到题目,这个题目涉及的知识还是满多的,又让我学到了不少。首先,我们要知道fibonacci素数的特征,fibonacci数列的第3、4项的2、3为fibonacci素数,第5项及其之后的素数项均为fibonacci素数,因此我们就要知道第22000个素数大概在什么范围。百度了之后发现10^6之内可以产生7万多个素数,因此我们可以先把10^6内的素数筛出来存到数组里,以便后面使用。

    下面我们就要知道从什么时候开始fibonacci数会超过9位,我测了一下第44个fibonacci数是最后一个9位及9位以内的fibonacci数,对应的就是第14个fibonacci素数,因此我们先可以预处理出15以内的结果,剩下的再用函数去算。

    在算的时候,我们首先要找到第n个fibonacci素数的项数x,然后再求F(x)的前9位即可,在求的时候为了确保有9位精度,我们选择用long double形式的快速幂去计算,并且每次计算完之后,要把结果卡在某个范围以下,这样是为了避免后续的运算会超过long double的表示范围。

#include
#include
#include
long long int fib[60]; int N, prime[1000010], p[100010]; long double a[60][4], b[4]; void prepare() {
int i, j, k, n; fib[0] = 0, fib[1] = 1; for(i = 2; i < 50; i ++) fib[i] = fib[i - 1] + fib[i - 2]; k = (int)sqrt((double)1000001); memset(prime, -1, sizeof(prime)); n = 0; for(i = 2; i <= k; i ++) if(prime[i]) {
p[n ++] = i; for(j = i * i; j < 1000001; j += i) prime[j] = 0; } for(; i < 1000001; i ++) if(prime[i]) p[n ++] = i; a[0][0] = a[0][1] = a[0][2] = 1; a[0][3] = 0; } void pow_mod(int n, int e) {
if(n == 1) {
a[e][0] = a[e][1] = a[e][2] = 1; a[e][3] = 0; return ; } pow_mod(n / 2, e + 1); a[e][0] = a[e + 1][0] * a[e + 1][0] + a[e + 1][1] * a[e + 1][2]; a[e][1] = a[e + 1][0] * a[e + 1][1] + a[e + 1][1] * a[e + 1][3]; a[e][2] = a[e + 1][2] * a[e + 1][0] + a[e + 1][3] * a[e + 1][2]; a[e][3] = a[e + 1][2] * a[e + 1][1] + a[e + 1][3] * a[e + 1][3]; if(n % 2) {
b[0] = a[e][0] * a[0][0] + a[e][1] * a[0][2]; b[1] = a[e][0] * a[0][1] + a[e][1] * a[0][3]; b[2] = a[e][2] * a[0][0] + a[e][3] * a[0][2]; b[3] = a[e][2] * a[0][1] + a[e][3] * a[0][3]; a[e][0] = b[0], a[e][1] = b[1], a[e][2] = b[2], a[e][3] = b[3]; } while(a[e][0] > 10000) a[e][0] /= 10, a[e][1] /= 10, a[e][2] /= 10, a[e][3] /= 10; } void solve() {
int i, j, n; long long int t; long double x; n = p[N - 1]; pow_mod(n - 1, 1); x = a[1][0]; while(x < 100000000) x *= 10; t = (long long int)x; printf("%lld\n", t); } int main() {
prepare(); while(scanf("%d", &N) == 1) {
if(N <= 2) printf("%s\n", N == 1 ? "2" : "3"); else if(N <= 14) printf("%lld\n", fib[p[N - 1]]); else solve(); } return 0; }

转载于:https://www.cnblogs.com/staginner/archive/2011/12/16/2290388.html

你可能感兴趣的文章
转:[Server] 在 Windows 上安裝 PHP 5.3 開發環境
查看>>
【IE6的疯狂之二】IE6中PNG Alpha透明(全集)
查看>>
第一个Shell脚本
查看>>
C++ 小笔记
查看>>
zabbix 安装rpm
查看>>
PhantomJS:Full web stack,No browser required
查看>>
Git远程操作详解
查看>>
java课后思考问题(七)
查看>>
5.9 容器
查看>>
创建oracle数据库的表空间、用户、目录、导入\导出文件等信息
查看>>
php禁止浏览器使用缓存页面的方法
查看>>
django的模型类管理器-----------数据库操作的封装
查看>>
java 回调
查看>>
CF1100E Andrew and Taxi 二分答案+拓扑排序
查看>>
子弹朝向问题的解决,移动方法的编写
查看>>
$("#id a") - $("#id .c a") = ?
查看>>
题目1034:寻找大富翁---用了sort()函数,注意头文件;
查看>>
Windows下Wamp装不上Memcache扩展
查看>>
js中数组的map()方法
查看>>
wpa破解学习实践
查看>>