hdu 3977

来源:互联网 发布:农村选举知乎 编辑:程序博客网 时间:2024/06/05 14:50
#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;}
原创粉丝点击