Define S[n] as the number of subsets of {1, 2, ..., n} that contain no consecutive integers. For each S[n], if for all i (1 ≤ i < n) gcd(S[i], S[n]) is 1, we call that S[n] as a Prime S. Additionally, S[1] is also a Prime S. For the Kth minimum Prime S, we'd like to find the minimum S[n] which is multiple of X and not less than the Kth minimum Prime S. Please tell us the corresponding (S[n] ÷ X) mod M.
Input
There are multiple test cases. The first line of input is an integer T indicating the number of test cases.
For each test case, there are 3 integers K (1 ≤ K ≤ 106), X (3 ≤ X ≤ 100) and M (10 ≤ M ≤ 106), which are defined in above description.
<h4< dd="">Output
For each test case, please output the corresponding (S[n] ÷ X) mod M.
<h4< dd="">Sample Input
1 1 3 10
<h4< dd="">Sample Output
1
SOLUTION:
Original: https: //blog.csdn.net/zy691357966/article/details/44857739
2. Feibolaqi properties
gcd (fib (n), fib (m)) = fib (gcd (n, m)) ( i.e., calculated from the start of a 112,358 sequences)
so that only when gcd (n , m) = 1 or 2 fib [n] and fib [m] coprime
S [n] = fib [n + 2]
Therefore, if the S [n] If a primeS
the n + 2 must be a prime number or 4, own paint know why the special 4 is
so constructed a special prime table
P [i] 3 4 5 7 11 13 ...................
therefore the K PrimeS is a fib [P [k]]
3. How to find the number divisible by X
From fib [P [k] to find that a start of a fib [P [k]] Number of% X == 0 to
Recording ansi = i;
4. cited congruence formula
(a/b)%c=(a%(b*c))/b
According to the calculation ansi
CODE:
#include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <algorithm> #include <iostream> #include <sstream> #include <string> #define oo 0x13131313 #define LL long long using namespace std; const int maxn=16000001; int K,X,M; int p[2000001],tot=0; bool yn[maxn]; struct node { LL mat[3][3]; }; node matmult(node a,node b,int mod) { node c; memset(c.mat,0,sizeof(c.mat)); for(int i=1; i<=2; i++) for(int j=1; j<=2; j++) for(int k=1; k<=2; k++) c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod; return c; } node quickmatpow(node a,int n,int mod) { node c; memset(c.mat,0,sizeof(c.mat)); c.mat[1][1]=1; c.mat[1][2]=0; c.mat[2][1]=0; c.mat[2][2]=1; while(n!=0) { if(n&1==1) c=matmult(c,a,mod); a=matmult(a,a,mod); n=n>>1; } return c; } void get_prime() { for(int i=2; i<maxn; i++) { if(yn[i]==false) { p[++tot]=i; for(int j=i; j<maxn; j=j+i) yn[j]=true; } } // printf("%d\n",tot); p[1]=3; p[2]=4; } void init() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); } int main() { // init(); get_prime(); int T; cin>>T; while(T--) { int ansi; int temp; node a,c; memset(a.mat,0,sizeof(a.mat)); memset(c.mat,0,sizeof(c.mat)); a.mat[1][1]=1,a.mat[1][2]=1,a.mat[2][1]=1,a.mat[2][2]=0; scanf("%d%d%d",&K,&X,&M); for(int i=p[K];; i++) { c=quickmatpow(a,i-2,X); temp=((c.mat[1][1]+c.mat[1][2]))%X; if(temp==0) { ansi=i; break; } } c=quickmatpow(a,ansi-2,M*X); temp=((c.mat[1][1]+c.mat[1][2]))%(M*X); printf("%d\n",temp/X); } return 0; }