线性筛
LL v[maxn],prime[maxn];//prime存质数,v判断是不是质数
int primes(LL n){
int m=0;
for(LL i=2;i<=n;i++){
if(v[i]==0){//i是质数
v[i]=i;prime[++m]=i;
}
for(int j=1;j<=m;j++){
if(prime[j]>v[i]||prime[j]>n/i)break;
v[i*prime[j]]=prime[j];
}
}
return m;
}
试除法
单判定数n
LL p[maxn],c[maxn];
void divide(LL n){
int m=0;
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){//i是质数
p[++m]=i,c[m]=0;
while(n%i==0) n/=i,c[m]++;//除掉所有的i
}
}
if(n>1)//n是质数
p[++m],c[m]=1;
}
二次剩余
template<typename T>
inline int pow(int x, T y)
{
int res = 1; x %= MOD;
for (; y; y >>= 1, x = (LL)x*x%MOD) if (y & 1) res = (LL)res*x%MOD;
return res;
}
inline int Quadratic_residue(const int a)
{
if (a == 0)return 0;
int b = (rand() << 14 ^ rand()) % MOD;
while (pow(b, (MOD - 1) >> 1) != MOD - 1)b = (rand() << 14 ^ rand()) % MOD;
int s = MOD - 1, t = 0, x, inv = pow(a, MOD - 2), f = 1;
while (!(s & 1))s >>= 1, t++, f <<= 1;
t--, x = pow(a, (s + 1) >> 1), f >>= 1;
while (t)
{
f >>= 1;
if (pow((int)((LL)inv*x%MOD*x%MOD), f) != 1) x = (LL)x*pow(b, s) % MOD;
t--, s <<= 1;
}
return min(x, MOD - x);
}
int main() {
int n;
scanf("%d", &n);
printf("%d\n", Quadratic_residue(n));
return 0;
}
欧拉降幂公式
LL euler_phi(LL n) {//求解欧拉函数
LL k = (LL)sqrt(n + 0.5);
LL ans = n;
for (int i = 2; i <= k; i++) {
if (n % i == 0) {
ans = ans / i * (i - 1);
while (n % i == 0) n /= i;
}
}
if (n > 1) ans = ans / n * (n - 1);
return ans;
}