???????????????????????O(√ n)?????????????????????O(slog3n)??????
???????????????p??????????(a??p)=1?????a^(p-1)≡1(mod p)????????p??????????a??p????????a??(p-1)?η?????p???????????1????????С?????
??????????????????????????????????????????????????????????
???????????????????????????????????????????p??????????a∈??1??p-1]??a∈Z?????a^(p-1) mod p??????1????????p????????????????s?Ρ?????a^(p-1) mod p?????????p-1д??????????(a*b)mod c=(a mod c)*b mod c????????t=log(p-1)??????????????翼???????????????????μ???????????log3(p-1)??????????п?????????
???????????????????????????????????????????
???????????????0<x<p??x^2 mod p =1 => x=1??p-1??
??????????p-1=(2^t)*u????p-1?u?????????????t??0????????????x[0]=a^u mod p ???????t?β????????p?????ε??????x[i]?????????????a^(p-1) mod p???????x[i]=1??x[i-1]??????1???????p-1??????p?????????????
???????????????????????????????????s?γ????????????2^(-s)???????????????????
?????????????????????????????????????a*b mod c ??????????????????????????????????????????????
????????????????
typedef unsigned long long LL;
LL modular_multi(LL x??LL y??LL mo)
{
LL t;
x%=mo;
for(t=0;y;x=(x<<1)%mo??y>>=1)
if (y&1)
t=(t+x)%mo;
return t;
}
LL modular_exp(LL num??LL t??LL mo)
{
LL ret=1??temp=num%mo;
for(;t;t>>=1??temp=modular_multi(temp??temp??mo))
if (t&1)
ret=modular_multi(ret??temp??mo);
return ret;
}
bool miller_rabbin(LL n)
{
if (n==2)return true;
if (n<2||!(n&1))return false;
int t=0;
LL a??x??y??u=n-1;
while((u&1)==0) t++??u>>=1;
for(int i=0;i<S;i++)
{
a=rand()%(n-1)+1;
x=modular_exp(a??u??n);
for(int j=0;j<t;j++)
{
y=modular_multi(x??x??n);
if (y==1&&x!=1&&x!=n-1)
return false;
///??????????????????n????1???????????????n???????
///????????x??????x^2≡1 (mod n)????x????????n???1??????‘???’???????1??-1????x????n???1???????????
x=y;
}
if (x!=1)///???????С???????n??????????a^(n-1)≡1(mod n).???n????????????
return false;
}
return true;
}