[MOBAN]二次剩余Cipolla算法

有关二次剩余的cipolla算法模板 原理可见https://blog.csdn.net/qq_33229466/article/details/79125057
int w;
const int mod = 1e9+9;
namespace MATH {
    int add(int x,int y) { x+=y; return x>=mod?x-mod:x; }
    int sub(int x,int y) { x-=y; return x<0?x+mod:x; }
    int mul(int x,int y) { return 1ll*x*y%mod; }
    int ksm(int a,int b) {
        int ans = 1;
        for(;b;b>>=1,a=mul(a,a))
            if(b&1) ans = mul(ans,a);
        return ans;
    }
}
using namespace MATH;
 
struct E{
    int re,im;
    friend E operator*(E aa,E bb) {
        return (E){ add( mul(aa.re,bb.re) , mul(mul(aa.im,bb.im),w) )  , add( mul(aa.re,bb.im) , mul(aa.im,bb.re)) }; 
    }
    friend int getksm(E a,int b) {
        E ans = (E){1,0};
        for(;b;b>>=1,a = a*a ) 
        if(b&1) {
            ans = ans*a;
        }
        return ans.re;
    }
};
 
namespace cipola{
        int getit(int n) {
            int oo = ksm(n,(mod-1)/2);
            if(oo==mod-1) return -1;
            if(oo==0) return 0;
            while(233) {
                int aa = rand()%mod;
                if( ksm(sub(mul(aa,aa),n),(mod-1)/2)!=mod-1) continue;
                w = sub(mul(aa,aa),n);
                return getksm((E){aa,1},(mod+1)/2);
            }
        }
     
}
 
posted @ 2019-01-09 15:20  Newuser233  阅读(9)  评论(0)    收藏  举报