LOJ 6465. 二平方和定理

SOL:

 由费马二平方和定理,解是存在且唯一的。

 那么x在高斯整数意义下(在高斯整数意义下,唯一分解定理同样成立),有两个互扼的非平凡约数。a+bi 与 a-bi、

   (a+bi)*(a-bi)=a*a+b*b=x,可见a和b就是我们要求的答案。

  我们找一个数k,使 x| k*k+1 ,那么 x|(k+i)(k-i)

  又因为gcd(a,b)=1,gcd(k,1)=1;

  所以gcd(k+i,k-i)=1(这样的写法其实不严谨,我只是表示k+i与k-i互质)

          gcd(a+bi,a-bi)=1

   故gcd(x,k+i)=a+bi 或 a-bi

   k的话,可以随机找。

   高斯整数上的gcd,可以类比整数上的gcd。

 

#include<bits/stdc++.h>
#define LO __int128
#define LL long long
#define pii pair<LL,LL>
#define x first
#define y second
using namespace std;
LL qsm(LL x,LL y,LL mo){
    static LL anw;
    for (anw=1,x%=mo;y;y>>=1,x=(LO)x*x%mo) if (y&1) anw=(LO)anw*x%mo;
    return anw;
}
pii operator + (pii a,pii b){
    return pii(a.x+b.x,a.y+b.y);
}
pii operator - (pii a,pii b){
    return pii(a.x-b.x,a.y-b.y);
}
pii operator * (pii a,pii b){
    return pii(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
pii operator % (pii a,pii b){
    LO fm=LO(b.x)*b.x+LO(b.y)*b.y;
    LO aa=LO(a.x)*b.x+LO(a.y)*b.y;
    LO bb=-LO(a.x)*b.y+LO(a.y)*b.x;
    return a-pii(llround(aa/(long double)fm),llround(bb/(long double)fm))*b;
}
pii gcd(pii a,pii b){
    if (b.x==0&&b.y==0) return a;
    return gcd(b,a%b);
}
int T; LL x,p,k; pii L;
int rand(){
    static int X=23333; return X^=X<<5,X^=X>>17,X^=X<<13;
}
signed main () {
    scanf("%d",&T);
    while (T--) {
        scanf("%lld",&x);
        while (1) {
            p=rand()%(x-2)+2;
            if (qsm(p,x-1>>1,x)==x-1){
                k=qsm(p,x-1>>2,x); 
                break;
            }
        }
        L=gcd(pii(x,0),pii(k,1));
        L.x=abs(L.x),L.y=abs(L.y);
        if (L.x>L.y) swap(L.x,L.y);
        printf("%lld %lld\n",L.x,L.y);
    } return 0;
}

 

posted @ 2018-07-15 15:22  泪寒之雪  阅读(943)  评论(0编辑  收藏  举报