[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);
}
}
}

浙公网安备 33010602011771号