UVA 10236 The Fibonacci Primes (斐波那契素数)

Description:

The Fibonacci number sequence is 1 , 1 , 2 , 3 , 5 , 8 , 13 1, 1, 2, 3, 5, 8, 13 and so on. You can see that except the first two numbers the others are summation of their previous two numbers. A Fibonacci Prime is a Fibonacci number which is relatively prime to all the smaller Fibonacci numbers. First such Fibonacci Prime is 2 2 , the second one is 3 3 , the third one is 5 5 , the fourth one is 13 13 and so on. Given the serial of a Fibonacci Prime you will have to print the first nine digits of it. If the number has less than nine digits then print all the digits.

Input

The input file contains several lines of input. Each line contains an integer N ( 0 < N 22000 ) N (0 < N ≤ 22000) which indicates the serial of a Fibonacci Prime. Input is terminated by End of File.

Output

For each line of input produce one line of output which contains at most nine digits according to the problem statement.

Sample Input

1
2
3

Sample Output

2
3
5

题意:

若某 F i b o n a c c i Fibonacci 数与任何比它小的 F i b o n a c c i Fibonacci 数互质,那么它就是 F i b o n a c c i Fibonacci 质数。给出 n n ,输出第 n n 个斐波那契素数,取数值的前9位数。

对于 F i b o n a c c i Fibonacci 序列,若 p p 是质数,则 f p f_{p} F i b o n a c c i P r i m e Fibonacci Prime

具体证明可以参考这篇博客:点击这里

然后直接使用线性筛的过程预处理就好了, O ( n ) O(n) 的复杂度。

AC代码:

#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define sd(n) scanf("%d", &n)
#define sdd(n, m) scanf("%d%d", &n, &m)
#define sddd(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define pd(n) printf("%d\n", n)
#define pc(n) printf("%c", n)
#define pdd(n, m) printf("%d %d\n", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n, m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld", &n)
#define sldd(n, m) scanf("%lld%lld", &n, &m)
#define slddd(n, m, k) scanf("%lld%lld%lld", &n, &m, &k)
#define sf(n) scanf("%lf", &n)
#define sc(n) scanf("%c", &n)
#define sff(n, m) scanf("%lf%lf", &n, &m)
#define sfff(n, m, k) scanf("%lf%lf%lf", &n, &m, &k)
#define ss(str) scanf("%s", str)
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define mem(a, n) memset(a, n, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define mod(x) ((x) % MOD)
#define gcd(a, b) __gcd(a, b)
#define lowbit(x) (x & -x)
typedef pair<int, int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
inline int read()
{
    int ret = 0, sgn = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            sgn = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        ret = ret * 10 + ch - '0';
        ch = getchar();
    }
    return ret * sgn;
}
inline void Out(int a) //Êä³öÍâ¹Ò
{
    if (a > 9)
        Out(a / 10);
    putchar(a % 10 + '0');
}

ll gcd(ll a, ll b)
{
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b)
{
    return a * b / gcd(a, b);
}
///快速幂m^k%mod
ll qpow(ll a, ll b, ll mod)
{
    if (a >= mod)
        a = a % mod + mod;
    ll ans = 1;
    while (b)
    {
        if (b & 1)
        {
            ans = ans * a;
            if (ans >= mod)
                ans = ans % mod + mod;
        }
        a *= a;
        if (a >= mod)
            a = a % mod + mod;
        b >>= 1;
    }
    return ans;
}

// 快速幂求逆元
int Fermat(int a, int p) //费马求a关于b的逆元
{
    return qpow(a, p - 2, p);
}

///扩展欧几里得
int exgcd(int a, int b, int &x, int &y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int g = exgcd(b, a % b, x, y);
    int t = x;
    x = y;
    y = t - a / b * y;
    return g;
}

///使用ecgcd求a的逆元x
int mod_reverse(int a, int p)
{
    int d, x, y;
    d = exgcd(a, p, x, y);
    if (d == 1)
        return (x % p + p) % p;
    else
        return -1;
}

///中国剩余定理模板0
ll china(int a[], int b[], int n) //a[]为除数,b[]为余数
{
    int M = 1, y, x = 0;
    for (int i = 0; i < n; ++i) //算出它们累乘的结果
        M *= a[i];
    for (int i = 0; i < n; ++i)
    {
        int w = M / a[i];
        int tx = 0;
        int t = exgcd(w, a[i], tx, y); //计算逆元
        x = (x + w * (b[i] / t) * x) % M;
    }
    return (x + M) % M;
}
const int N = 1e6 + 10;
int ans[22010];
bool vis[N];

void init()
{
    ll a = 0, b = 1, tmp, i, j;
    int cnt;
    for (cnt = 1, i = 2; cnt < 22010; i++)
    {
        tmp = a + b, a = b, b = tmp; //模拟Fibonacci数列
        if (b >= 1e18)
            b /= 10, a /= 10; //不能超界
        if (!vis[i])
        {
            tmp = b;
            while (tmp >= 1e9)
                tmp /= 10;
            ans[cnt++] = tmp;
            for (j = i * i; j < N; j += i)
                vis[j] = true; //埃氏筛素数
        }
    }
    ans[1] = 2;
    ans[2] = 3;
}

int main()
{
    mem(vis, 0);
    init();
    int n;
    while (~sd(n))
        pd(ans[n]);
    return 0;
}
发布了679 篇原创文章 · 获赞 410 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/qq_43627087/article/details/104330308