SGU_511_Fermat's Last Theorem

来源:互联网 发布:python股票预测准确率 编辑:程序博客网 时间:2024/06/06 01:33

PRO IS HERE

x^n + y^n = z^n (mod p)

假设p的原根是r

我们设 x=r^a,y=r^b,z=r^c;

原方程化为

r^an + r^bn = r^cn (mod p)

令R=r^n

设a<=b

=> 1 + R^(b-a) = R^(c-a) (mod p)     (c>=a)

或者

R^(a-c) + R^(b-c) = 1 (mod p)         (c<a)


我们枚举R^k

若有1+R^k1=R^k2 或 R^k1+R^k2=1则有解

枚举时若R^k出现循环则break。


CODE:

#include<cstdio>#include<cstring>#include<iostream>using namespace std;#define LL int#define nMax 1000001int a[nMax],l;inline int pow_mod(int a,int n,int mod){    long long y=1LL,b=(long long)a;    while (n>0){        if (n&1) y=y*b%mod;        n>>=1;        b=b*b%mod;    }    return (int)y;}inline int g_test(int g,int p){    for(register LL i=0;i<l;i++) if(pow_mod(g,(p-1)/a[i],p)==1) return 0;    return 1;}int primitive_root(int p){    int tmp=p-1;    l=0;    for(register int i=2;i<=tmp/i;i++) if(tmp%i==0){        a[l++]=i;        a[l++]=tmp/i;        //while(tmp%i==0) tmp/=i;    }    int g=1,j;    while(1){        for(j=0;j<l;j++) if(pow_mod(g,tmp/a[j],p)==1) break;        if(j>=l) return g;        g++;    }}int A[nMax]={0},B[nMax];int n,p;int x,y,z,s,R,ok,s1,s2;int j;int r;#define bug puts("Fuck");int main(){#ifndef ONLINE_JUDGEfreopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);#endif    int t;    int cas=1;    scanf("%d",&t);    while(t--){        scanf("%d%d",&n,&p);        r=primitive_root(p);        R=pow_mod(r,n,p);        ok=0;        s=1;        //A[1]=cas;B[1]=0;        for(register LL i=0;i<p && !ok;i++){            if(i) s=(long long)s*R%p;            if(A[s]==cas) break;            A[s]=cas;B[s]=i;            s1=1+s;if(s1>=p) s1=0;            s2=1-s+p;while(s2>=p) s2=0;            if(A[s1]==cas){                j=B[s1];                x=1,y=pow_mod(r,i,p),z=pow_mod(r,j,p);                ok=1;break;            }else if(A[s2]==cas){                j=B[s2];                x=pow_mod(r,i,p),y=pow_mod(r,j,p),z=1;                ok=1;break;            }            //A[s]=cas;B[s]=i;        }        if(ok) printf("%d %d %d\n",x,y,z);        else printf("-1\n");        cas++;    }return 0;}


原创粉丝点击