#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int N = 800005;
struct Marix
{
int val[2][2];
};
Marix mutli(Marix a,Marix b,ll mod)
{
Marix c;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++) {
c.val[i][j]=0;
for(int k=0;k<2;k++) {
c.val[i][j]+=(a.val[i][k]*b.val[k][j]);
c.val[i][j]%=mod;
}
}
return c;
}
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);}
ll prime[N],tot=0;
void Euler_prime() {
bool check[N];
memset(check,0,sizeof(check));
for(int i=2;i<=N;i++) {
if(!check[i]) prime[++tot]=i;
for(int j=1;j<=tot;j++) {
if(prime[j]*i>N) break;
check[prime[j]*i]=1;
if(i%prime[j]==0) break;
}
}
}
ll num[N],time[N],cnt=0;
void solve(ll n)
{
memset(time,0,sizeof(time));
ll t=ll(sqrt(n*1.00));
for(int i=1;prime[i]<=t;i++) {
if(n%prime[i]==0) {
num[++cnt]=prime[i];
while(n%prime[i]==0) {
time[cnt]++;
n/=prime[i];
}
}
}
if(n>1) {
num[++cnt]=n;
time[cnt]++;
}
}
ll quick_pow(ll a,ll b,ll c)
{
ll ans=1;
for(;b;b>>=1) {
if(b&1) { ans*=a; ans%=c;}
a*=a;
a%=c;
}
return ans;
}
Marix I,M;
void init()
{
M.val[0][0]=M.val[0][1]=M.val[1][0]=1; M.val[1][1]=0;
I.val[0][0]=I.val[1][1]=1; I.val[0][1]=I.val[1][0]=0;
}
Marix quick_Mpow(Marix a,ll k,ll mod)
{
Marix c=I,p=a;
for(;k;k>>=1) {
if(k&1) c=mutli(c,p,mod);
p=mutli(p,p,mod);
}
return c;
}
ll legendre(ll a,ll p)
{
if(quick_pow(a,(p-1)>>1,p)==1) return 1;
else return -1;
}
ll fac[N],c;
void find_fac(ll n)
{
c=0;
ll t=(ll)(sqrt(n*1.0));
for(int i=1;i<=t;i++) {
if(n%i==0) {
if(i*i==n) fac[++c]=i;
else {
fac[++c]=i;
fac[++c]=n/i;
}
}
}
}
ll find_loop(ll n)
{
solve(n);
ll ans=1;
for(int i=1;i<=cnt;i++) {
ll rec=1;
if(num[i]==2) rec=3;
else if(num[i]==3) rec=8;
else if(num[i]==5) rec=20;
else {
if(legendre(5,num[i])==1)
find_fac(num[i]-1);
else
find_fac(2*(num[i]+1));
sort(fac,fac+c);
for(int k=1;k<=c;k++) {
Marix a=quick_Mpow(M,fac[k]-1,num[i]);
ll x=(a.val[0][0]%num[i]+a.val[0][1]%num[i])%num[i];
ll y=(a.val[1][0]%num[i]+a.val[1][1]%num[i])%num[i];
if(x==1&&y==0) {
rec=fac[k];
break;
}
}
}
for(int k=1;k<time[i];k++)
rec*=num[i];
ans=lcm(ans,rec);
}
return ans;
}
int main()
{
ll n,T;
init();
Euler_prime();
ll kase=0;
cin>>T;
while(T--)
{
cin>>n;
c=0;
cnt=0;
printf("Case #%lld: %lld\n",++kase,find_loop(n));
}
return 0;
}
hdu 3977
最新推荐文章于 2019-10-23 19:15:20 发布