题目描述:
求解Prime Fibonacci 数列 P 的第 N 位(即该数列中不能被别的 Fibonacci 数整除的数)。 ( P 1 = 2 , P 2 = 3 , P 3 = 5 , P 4 = 13 ⋯ ) (P_1=2, P_2=3, P_3=5, P_4=13⋯) (P1=2,P2=3,P3=5,P4=13⋯)
由于答案过大,所以答案 P n 3   m o d   m \frac{P_n}{3} \bmod m 3Pnmodm (题目保证gcd(3, m) = 1)
输入描述:
多组输入,每组数据输入 n , m n, m n,m两个正整数(1 ≤ \le ≤ n ≤ \le ≤ 500000, 4 ≤ \le ≤ m ≤ \le ≤ 1000000000,组数不大于 50000)
输出描述:
对于每组测试数据输出
P
n
3
 
m
o
d
 
m
\frac{P_n}{3} \bmod m
3Pnmodm
答案保留 9 位字符,不足则补 *
输入样例:
2 5
输出样例:
********1
思路
根据Prime Fibonacci数列性质:对于原始Fibonacci数列,从F(5)开始,某项为Fibonacci质数当且仅当它的项数为质数,所以初始化得到prim[]质数序列,即Prime Fibonacci数列在原始Fibonacci数列中的项数序列,从而可以得到 P n P_n Pn在原始Fibonacci数列的哪一项;
然后快速Fibonacci数列的方法得到该项mod m的值,结果就是该值乘以3对于m的逆元mod m。
更多题解请关注 doubleQ2018’s GitHub
ac代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 7400000;
bool vis[maxn+10];
long long pri[maxn+10];
long long n, mod, ni;
struct Matrix {
long long ma[2][2];
};
Matrix mul(Matrix A,Matrix B) {
Matrix C;
C.ma[0][0] = C.ma[0][1] = C.ma[1][0] = C.ma[1][1] = 0;
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++) {
for(int k = 0; k < 2; k++) {
C.ma[i][j] = (C.ma[i][j] + A.ma[i][k] * B.ma[k][j]) % mod;
}
}
}
return C;
}
Matrix pow_mod(Matrix A, long long n) {
Matrix B;
B.ma[0][0] = B.ma[1][1] = 1;
B.ma[0][1] = B.ma[1][0] = 0;
while(n) {
if(n & 1) B = mul(B,A);
A = mul(A, A);
n >>= 1;
}
return B;
}
long long quick_fibonacci(long long n) {
Matrix A;
A.ma[0][0] = 1; A.ma[0][1] = 1;
A.ma[1][0] = 1; A.ma[1][1] = 0;
Matrix ans = pow_mod(A, n);
return ans.ma[0][1];
}
long long extend_gcd(long long a, long long b, long long &x, long long &y) {
if (b == 0) {
x = 1, y = 0;
return a;
}
else {
long long r = extend_gcd(b, a % b, y, x);
y -= x * (a / b);
return r;
}
}
long long inv(long long a, long long n) {
long long x, y;
extend_gcd(a, n, x, y);
x = (x % n + n) % n;
return x;
}
int main() {
int cur = 5;
long long i, j;
for(i = 2; i <= maxn; i++) vis[i] = false;
for(i = 2; i <= maxn; i++) {
if(!vis[i]){
for(j = i*i; j <= maxn; j += i) vis[j] = 1;
}
}
for(i = 11; i <= maxn; i++)
if(vis[i] == 0) {
pri[cur++] = i;
}
while(cin >> n >> mod){
ni = inv(3, mod);
long long ans;
if(n == 1) ans = 2*ni%mod;
else if(n == 2) ans = 3*ni%mod;
else if(n == 3) ans = 5*ni%mod;
else if(n == 4) ans = 13*ni%mod;
else ans = quick_fibonacci(pri[n])*ni%mod;
string res = to_string(ans);
if(res.size() < 9) res = string(9-res.size(), '*') + res;
cout << res << endl;
}
}
更多题解请关注 doubleQ2018’s GitHub