0、一些结论
- (hdu3501)求1…N中与N互质的数的和:ans=phi(n)*n/2
1、欧几里德算法
int gcd(int a, int b)
{
return b == 0 ? a : gcd(b , a%b);
}
int lcm(int a, int b)
{
return a/gcd(a,b)*b;//防止溢出
}
2、Eratosthenes筛法
int m = sqrt(int n+0.5);
memset(vis, 0, sizeof(vis));
for(int i = 2; i <= m; i++)
{
if(!vis[i])
for(int j = i*i; j <= n; j += i)
{
vis[j] = 1;
}
}
3、扩展欧几里德算法
4、同余与模算术
同余:a 与 b 在模 m 的情形下同余,即为 a, b 除以 m 的余数相等。
剩余系:mod m = k 的整数。
1)同余定理
//(a+b)%n=(a%n+b%n)%n
//(a-b)%n=(a%n-b%n+n)%n
//a*b%=(a%n)*(b%n)%n;
int mul_mod(int a, int b, int n)
{
a %= n;
b %= n;
return (int)((long long)a * b % n);
}
2)大数取模
scanf("%s%d",n, &m);
int len = strlen(n);
int ans = 0;
for(int i = 0; i < len; i++)
{
ans=(int)((long long)ans*10 + n[i] - '0') % m);
}
printf("%d\n",ans);
3)幂取模
int pow_mod(LL a,LL n,int m)
{
if(n==0) return 1;
LL x=pow_mod(a,n/2,m);
LL ans=x*x%m;
ans=ans%m;
if(n%2==1) ans=ans*a%m;
return (int)ans;
}
4)矩阵快速幂
struct Matrix
{
int mp[N][N];
};
Matrix Mul(Matrix a,Matrix b)
{
int i,j,k;
Matrix c;
for(i=0; i<N; i++)
for(j=0; j<N; j++)
{
c.mp[i][j]=0;
for(k=0; k<N; k++)
{
c.mp[i][j]+=a.mp[i][k]*b.mp[k][j];
c.mp[i][j]%=M;
}
}
return c;
}
/*
Matrix Pow(Matrix t,int n)
{
if(n==1) return t;
Matrix c=Pow(t,n/2);
if(n&1)
return Mul(Mul(c,c),t);
else
return Mul(c,c);
}
*/
Matrix Pow(Matrix a,int n)
{
Matrix c;
for(i=0;i<N;i++)
c.mp[i][i]=1;
while(n)
{
if(n&1) c=Mul(c,a);
a=Mul(a,a);
n/=2;
}
return c;
}
5、欧拉函数(计算小于n且与n互素的整数个数)
1)计算小于n且与n互素的整数个数
int euler_phi(int n)
{
int m=(int)sqrt(n+0.5);
int ans=n;
for(int i=2; i<=m; 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;
}
2)1~n中所有数的欧拉phi函数值
void phi_table(int n)
{
for(int i=2;i<=n;i++) phi[i]=0;
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(!phi[i])//判断素数
{
for(int j=i;j<=n;j+=i)
{
if(!phi[j]) phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
}
}
6、乘法逆元
- 若 (k, m) = 1,则存在一个
k−1
,使得
k−1
k
=
k k−1 = 1 (mod m),称其为 k 在模 m 下的乘法逆元。 - Bezout 定理:如果 (a, b) = g,那么存在整数 x, y 使得 ax + by = g。