椭圆曲线质因数分解2

Upd: 写了一点资料. https://pan.baidu.com/s/1GyzysqQUVuUyI8Bsqs9O-g

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
typedef uint64_t u64;
typedef __uint128_t u128;
typedef __int128_t i128;
namespace Timer{
    template
    std::pair Time(T(*func)(Args...ar),Args...ar){
        using hrc=std::chrono::high_resolution_clock;
        hrc::time_point start=hrc::now();
        T out=func(ar...);
        return std::pair(u64(std::chrono::duration_cast(hrc::now()-start)),out);
    }
}
inline u128 getint() {
    u128 ret=0;
    bool ok=0,neg=0;
    for(;;) {
        int c=getchar();
        if(c>='0'&&c<='9') ret=(ret<<3)+ret+ret+c-'0',ok=1;
        else if(ok)return neg?0-ret:ret;
        else if(c=='-') neg=1;
    }
}
void printint(u128 n) {
    const u64 ten18=u64(1e18);
    if (n>=ten18) printf("%llu%018llu",u64(n/ten18),u64(n%ten18));
    else printf("%llu",u64(n));
}
#define rep(i,a,n) for (int i=a;i>64,a_lo=u64(a);
        u64 b_hi=b>>64,b_lo=u64(b);
        u128 p01=u128(a_lo)*b_lo;
        u128 p12=u128(a_hi)*b_lo+u64(p01>>64);
        u64 t_hi=p12>>64,t_lo=p12;
        p12=u128(a_lo)*b_hi+t_lo;
        u128 p23=u128(a_hi)*b_hi+u64(p12>>64)+t_hi;
        return u256(u64(p01)|(p12<<64),p23);
    }
    u128 lo,hi;
};
struct Mont{
    Mont(u128 n):mod(n) {
        inv=n;
        rep(i,0,6) inv*=2-n*inv;
        r2=-n%n;
        rep(i,0,4) if ((r2<<=1)>=mod) r2-=mod;
        rep(i,0,5) r2=mul(r2,r2);
    }
    u128 reduce(u256 x) const {
        u128 y=x.hi-u256::mul128(x.lo*inv,mod).hi;
        return i128(y)<0?y+mod:y;
    }
    u128 reduce(u128 x) const { return reduce(u256(x,0)); }
    u128 init(u128 n) const { return reduce(u256::mul128(n,r2)); }
    u128 mul(u128 a,u128 b) const { return reduce(u256::mul128(a,b)); }
    u128 mod,inv,r2;
};
// the Min-25 montgomery form manipulator
u128 ctz(u128 x){int a=__builtin_ctzll(u64(x>>64))+64,b=__builtin_ctzll(u64(x));return u64(x)?b:a;}
u128 gcd(u128 a,u128 b) {
    if (b==0) return a;
    int shift=ctz(a|b);
    b>>=ctz(b);
    while (a) {
        a>>=ctz(a);
        if (a>=1,a>>=1;
    }if(b>a)std::swap(a,b),std::swap(alpha,beta);
    while(b&&(a^b)){
        a-=b;alpha-=beta;
        while(!(a&1)){
            if(alpha&1)alpha+=b_or;
            alpha>>=1,a>>=1;
        }if(b>a)std::swap(a,b),std::swap(alpha,beta);
    }
    if(a==b)b=0,alpha-=beta,std::swap(alpha,beta);
//  putchar(':'),printint(u128(alpha)),putchar(' '),printint(u128(beta)),putchar('\n');
//  putchar(':'),printint(u128(-alpha)),putchar(' '),printint(u128(-beta)),putchar('\n');
    if(truth)alpha=b_or-alpha;
    alpha=alpha%b_or;
    if(alpha<0)alpha+=b_or;
    if(a!=1)return 0;
    return alpha;
}
//invert and gcd
u64 sqrt_approx(u64 x){
    u64 approx=sqrt(double(x));
    return (approx+x/approx)>>1;
}
u64 sqrt(u64 x){
    u64 approx=sqrt(double(x));
    u64 apt=(approx+x/approx)>>1;
    approx=apt*apt;
    if(approx>x)return apt-1;
    if(x-approx>=2*apt-1)return apt+1;
    return apt;
}
u128 sqrt(u128 r){
    if(!(r>>64))return sqrt(u64(r));
    int cnt=(((64-__builtin_clzll(u64(r>>64)))+1)|1)^1;
    u128 approx=u128(sqrt_approx(u64(r>>cnt)))<<(cnt/2);
    approx=(approx+r/approx)>>1;
    u128 apt=u128(u64(approx))*u128(u64(approx));
    return approx-((r-apt)>>127);
}
// fast int128 square root
#define ModularManipulate \
    u128 n=Modu->mod; \
    const auto add=[&] (u128 x,u128 y) { return (x+=y)>=n?x-n:x; }; \
    const auto sub=[&] (u128 x,u128 y) { return i128(x-=y)<0?x+n:x; }; \
    const auto mul=[&] (u128 x,u128 y) { return Modu->mul(x,y); }; \
    const auto get=[&] (u128 x)        { return Modu->reduce(x); }; \
    const auto set=[&] (u128 x)        { return Modu->init(x); }; \
    const auto dbl=[&] (u128 x)        { return (x<<=1)>=n?x-n:x; };

u128 invert(u128*inv,u128*lis,int len,Mont*Modu){
    ModularManipulate
    for(int i=1;i=0;i-=2){
        if(f)ca[0]=mul(ca[0],ca[0]),ca[0]=mul(ca[0],ca[0]);
        int q=(exp>>i)&3;
        if(q)f=1,ca[0]=mul(ca[0],ca[q]);
    }return ca[0];
}
u128 Double(affine*p1,int len,Mont*Modu){
    ModularManipulate
    u128*inv=tempui[0],*invr=tempui[1];
    for(int i=0;i>=1;
    }return res;
}
#define prr(x) printpoints(x,len,Modu)
void printpoints(affine*af,int len,Mont*Modu){
    ModularManipulate
    printf("Count:\n%d\n[",len);
    for(int i=0;i>=2;
//  prr(p1);
    while(Na!=1){
        int op=Na&3;
        u128 k=Double(p1,len,Modu);
//      puts("*2");
//      prr(p1);
        if(k)return k;
        if(op==1)k=Add(tem,p1,len,Modu);//,puts("+1"),prr(p1),prr(tem);
        else if(op==3)k=Sub(tem,p1,len,Modu);//,puts("-1"),prr(p1),prr(tem);
        if(k)return k;
        Na>>=2;
    }return 0;
}
u128 InitPoints(u128*param,affine*points,int len,Mont*Modu){
    ModularManipulate
    u128 five=set(5),two=set(2),one=set(1);
    for(int cn=0;cn>1,rt=0;
        while(rt=30)st-=30,++rt;
            if(st>=30)st-=30,++rt;
        }
    }
    void PrintMask(u32*a,u32 len){
        printf("Mask of len %u\n",len*60);
        for(u32 i=0;i main(ull ma){
        ull tma,tmx;
        tma=(ma-1)/60+1;
        tmx=tma*60;//upper limit
        u32*sieve=new u32[tma];// getting a sieve ready
        u32*maske=new u32[7429];
        std::fill(sieve,sieve+tma,mask);
        for(int i=0;i<6;++i)
            Apply_mask(sieve,maske,tma,Gen_mask(maske,i));

        ull preseg=std::min(tmx,ull(sqrt(double(ma))/60)+1);
        u32 j=61;
        for(;ull(j)*j<=preseg*60;j+=2){
            u32 v=j/60,u=(j%60)>>1;
            if(!(sieve[v]&(1<>1;
                while(rt=30)st-=30,++rt;
                }
                pr[prl][0]=v;
                pr[prl][1]=u;
                pr[prl][2]=rt;
                pr[prl][3]=st;
                prl++;
            }
        } // Non-segmented sieve core
        if(preseg==tmx)goto end;
        for(u32 segl=preseg;segl>1;
                if(!(sieve[v]&(1<>1;
                    pr[prl][0]=v;
                    pr[prl][1]=u;
                    pr[prl][2]=rt;
                    pr[prl][3]=st;
                    prl++;
                }
            }
            for(int i=0;i=30)st-=30,++rt;
                }
                pr[i][0]=v;
                pr[i][1]=u;
                pr[i][2]=rt;
                pr[i][3]=st;
            }
        }
        end:
        sieve[0]=pr60_m;
        std::vector ret;
        ret.push_back(2);
        for(u32 i=0;i primes){
    u128*param=tempui[2];
    Mont Mod(N);
    Mont*Modu=&Mod;
    ModularManipulate
    for(int i=0;iSmoothBound)break;
        u64 t=i,g=SmoothBound/i;
        while(t<=g)t*=i;
        ret=FastMultiply(plist,t,curve_count,Modu);
//      printf("Mult %llu\n",t);
//      printpoints(plist,curve_count,&Mod);
        if(ret)return ret;
    }
    return 1;
}
void Test(u128 N,int SmoothBound,int curve_count,std::vector primes){
    u128*param=tempui[2];
    affine*plist=tempaff[2];
    affine*plist2=tempaff[3];
    Mont Mod(N);
    Mont*Modu=&Mod;
    ModularManipulate
    for(int i=0;i pr=Sieve::main(1000000);
    u128 p=factor(inp,50000,160,pr);
    u128 q=inp/p;
    if(q

你可能感兴趣的:(椭圆曲线质因数分解2)