Problem Description
The so-called best problem solver can easily solve this problem, with his/her childhood sweetheart.
It is known that y=(5+26√)1+2x.
For a given integer x (0≤x<232) and a given prime number M (M≤46337), print [y]%M. ([y] means the integer part of y)
Input
An integer T (1<T≤1000), indicating there are T test cases.
Following are T lines, each containing two integers x and M, as introduced above.
Output
The output contains exactly T lines.
Each line contains an integer representing [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
没想到要找循环节,一开始想的欧拉降幂,后来发现自己是个傻子,无理数,和有理数。看到题解说是找循环节,这恐怕是解决巨长数列 某个位置上的数的有效办法。
构造+找循环节
#include<cstdio>
using namespace std;
#define rep(i,a,b) for(int i=a;i<b;i++)
typedef long long LL;
const int N=50000;
LL pow_mod(LL base,LL n,LL mod){
LL ans=1;
while(n){
if(n&1)ans=ans*base%mod;
base=base*base%mod;
n>>=1;
}
return ans%mod;
}
/*
能不取模,就不要取
*/
int a[N];
int get_loop(LL mod){
a[0]=10;if(a[0]>=mod)a[0]=a[0]%mod;
a[1]=98;if(a[1]>=mod)a[1]=a[1]%mod;
rep(i,2,N){
a[i]=(10LL*a[i-1]-1LL*a[i-2]+mod)%mod;
if(a[i-1]==a[0]&&a[i]==a[1]){
return i-1;
}
//printf("i:%d %lld\n",i,a[i]);
}
}
int main(){
int T;
scanf("%d",&T);
rep(kase,0,T){
LL x,mod;
scanf("%lld %lld",&x,&mod);
int loop=get_loop(mod);
printf("Case #%d: ",kase+1);
int num=pow_mod(2LL,x,loop);
//printf("loop:%lld num:%lld\n",loop,num);
printf("%d\n",(a[num]-1+mod)%mod);
}
return 0;
}