The so-called best problem solver can easily solve this problem, with his/her childhood sweetheart.
It is known that y=(5+26–√)1+2xy=(5+26)1+2x.
For a given integer x (0≤x<232)x (0≤x<232) and a given prime number M (M≤46337)M (M≤46337), print [y]%M[y]%M. ([y][y] means the integer part of yy)
Input
An integer T (1<T≤1000)T (1<T≤1000), indicating there are TT test cases.
Following are TT lines, each containing two integers xx and MM, as introduced above.
Output
The output contains exactly TT lines.
Each line contains an integer representing [y]%M[y]%M.
Sample Input
7 0 46337 1 46337 3 46337 1 46337 21 46337 321 46337 4321 46337
Sample Output
Case #1: 97 Case #2: 969 Case #3: 16537 Case #4: 969 Case #5: 40453 Case #6: 10211 Case #7: 17947
思路:遇到带根号的式子,想到共轭构造斐波那契函数。详见:戳这里。因此我们构造此斐波那契额数列为
,带入公示知:
易知,an是整数,由于所要求的结果是只取y的整数部分,而该式的后一部分是小于1的小数。因此若我们相求y的整数部分,只需求an -1即可。
由于斐波那契额数列取于一个数 是一定遵循循环节的。因此我们找到循环姐,再求an即可
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include<map>
#include<cstring>
#define ll long long
using namespace std;
ll rm[1008611],a[1008611];
ll x,m;
ll q_pow(ll b,ll mod){
ll ans = 1;
ll num = 2;
while(b){
if(b & 1)
ans = ans * num % mod;
b >>= 1;
num = num * num % mod;
}
return ans;
}
ll solve(){
ll n,ans;
n=(q_pow(x, rm[m])+1)%rm[m];
a[0]=2%m;
a[1]=10%m;
for(ll i=2;i<=n;i++){
a[i]=(10*a[i-1]-a[i-2]+m)%m;
}
ans=(a[n]-1+m)%m;
return ans;
}
void init(){
if(rm[m]!=0)return;//若之前找过这个循环节,则直接return
a[0]=2%m;
a[1]=10%m;
for(int i=2;;i++){
a[i]=(10*a[i-1]-a[i-2]+m)%m;
if(a[i-1]==a[0]&&a[i]==a[1]){
rm[m]=i-1;
break;
}
}
}
int main(){
ll t,ca=1;
cin>>t;
memset(rm, 0, sizeof(rm));
while(t--){
cin>>x>>m;
init();//找循环节rm
ll ans=solve();
printf("Case #%lld: %lld\n",ca++,ans);
}
return 0;
}