公约数
GCD
LL GCD( LL a,LL b )
{
return b==0?a:GCD(b,a%b);
}
EX_GCD
LL EX_GCD( LL a,LL b,LL &x,LL &y )//ax+by=gcd(a,b)
{
LL d=a;
if( !b ) x=1;y=0;
else {
d=EX_GCD(b,a%b,y,x);
y-=a/b*x;
}
return d;//返回最大公因数
}
/*
求a * x + b * y = c的整数解。
1、先计算Gcd(a,b),若n不能被Gcd(a,b)整除,则方程无整数解;否则,在方程两边同时除以Gcd(a,b),得到新的不定方程a' * x + b' * y = c',此时Gcd(a',b')=1;
2、利用上面所说的欧几里德算法求出方程a' * x + b' * y = 1的一组整数解x0,y0,则c' * x0,c' * y0是方程a' * x + b' * y = c'的一组整数解;
3、根据数论中的相关定理,可得方程a' * x + b' * y = c'的所有整数解为:
x = c' * x0 + b' * t
y = c' * y0 - a' * t
(t为整数)
*/
素数
素数的三种筛法
朴素算法 //O( n*sqrt(n) )
bool Isprime( LL n )
{
for( LL i=2;i*i<=n;i++ )
if( n%i==0 ) return false;
return true;
}
Eratosthenes筛法 //O( n*log n )
void Eratosthenes( int n )
{
memset(Isprime,true,sizeof(Isprime));
for( int i=2;i<=n;i++ )
{
if( Isprime(i) )
for( int j=i*i;j<=n;j+=i )
Isprime[j]=false;
}
}
欧拉算法 //O(n)
void Euler(int n)
{
memset(Isprime,0,sizeof(Isprime));
for( int i=2;i<=n;i++ )
{
if( !Isprime[i] )
prime[cnt++]=i;
for( int j=0;j<cnt;j++ )
{
if( prime[j]*i>n ) break;
Isprime[ prime[j]*i ] =true; //与下一行代码不可交换
if( i%prime[j]==0 ) break;
}
}
}
幂运算
快速幂 //O(log n)
LL Pow( LL x,LL n )
{
LL res=1;
while(n){
if( n&1 ) res*=x;
x*=x;
n>>=1;
}
return res;
}