(一)约数
1.算数基本定理的推论
N 的正约数个数为
(c1+1)(c2+1)(c3+1)…(cn+1)
N 的所有正约数的和为
(1+p1+p1 ^ 2 +p1 ^ 3+ p14…p1c1)…(1+pm+ pm^2 + …+pm^cm);
2.求正约数的集合----试除法
int f[1600],m=0;
for(int i=1;i*i<=n;i++){
if(n%i==0){
f[++m]=i;
if(i!=n/i) f[++m]=n/i;
}
}
for(int i=1;i<=m;i++)
cout<<f[i]<<endl;
3.试除法的推论
一个整数 N 的约数个数上界为2*√N;
4.求1~N 每个数的正约数集合——倍数法
vector<int>f[22222];
for(int i=1;i<=n;i++)
for(int j=1;j<=n/i;j++)
f[i*j].push_back(i);
for(int i=1;i<=n;i++){
for(int j=0;j<f[i].size();j++)
cout<<f[i][j] <<endl;
}
5.倍数法的推论
1~N 每个数的约数个数的总和大约为NlogN;
6.最大公约数和最小公倍数
1.唯一分解定理
2.九章算术更相减损法
3.欧几里得算法(最常用求最大公约数的方法)
int gcd(int a,int b){
if(b==0) return a;
else return gcd(b,a%b);
}
4.二进制算法(主要针对大整数求)
int base=10000;
int init(int a[]) {
string s;
cin>>s;
int l=s.length(),i,j;
for(i=0; i<l; i++) {
j=(l-i+3)/4;
a[j]=a[j]*10+s[i]-'0';
}
a[0]=(l+3)/4;
}
int Comp(int a[],int b[]) {
if(a[0]>b[0]) return 1;
if(a[0]<b[0]) return -1;
for(int i=a[0]; i>=1; i--)
if(a[i]>b[i]) return 1;
else if(a[i]<b[i]) return -1;
return 0;
}
void div(int a[],int k) {// a/k;
int i,t=0;
for(i=a[0]; i>=1; i--) {
t=t*base+a[i];
a[i]=t/k;
t%=k;
}
while(a[a[0]]==0&&a[0]>0) a[0]--;
}
void Minus(int a[],int b[]) {// a=a-b;
for(int i=1; i<=a[0]; i++) {
a[i]-=b[i];
if(a[i]<0) {
a[i+1]--;
a[i]+=base;
}
}
while(a[a[0]]==0&&a[0]>0) a[0]--;
}
void Gcd(int a[],int b[],int t) {
if(Comp(a,b)==0) {//比大小
T=t;
return;
}
if(Comp(a,b)<0) {
Gcd(b,a,t);
return ;
}
int ta,tb;
if(a[1]%2==0) {
div(a,2);
ta=1;
} else t1=0;
if(b[1]%2==0) {
div(b,2);
tb=1;
} else tb=0;
if(ta&&tb) Gcd(a,b,t+1);//都为偶数
else if(!ta&&!tb) {//都为奇数
Minus(a,b);
Gcd(a,b,t);
} else Gcd(a,b,t);//一奇一偶
}