一 素数
1 判断素数 O(sqrt(n))
bool is_prime(int n) //判断素数 O(sqrt(n))
{
if(n<2) return false;
for(int i=2;i<=n/i;i++)
if(n%i==0) return false;
return true;
}
2 分解质因数 O(sqrt(n))
void divide(int n) //分解质因数 O(sqrt(n))
{
for(int i=2;i<=n/i;i++)
{
if(n%i==0)
{
int s=0;
while(n%i==0)
{
n/=i;
s++;
}
printf("%d %d\n",i,s);
}
}
if(n!=1) printf("%d %d\n",n,1); //可能有大于sqrt(n)的质因子
}
3 埃氏筛 O(nlognlogn)
void sieve(int n) //埃氏筛法 O(nloglogn)
{
for(int i=2;i<=n;i++)
{
if(!st[i])
{
primes[cnt++]=i;
for(int j=2*i;j<=n;j+=i) st[j]=true;
}
}
}
//primes[] 记录素数
//st[] 表示是否为素数
4 欧拉筛(线性筛) O(n)
void sieve(int n) //欧拉筛法 O(n)
{
for(int i=2;i<=n;i++)
{
if(!st[i]) primes[cnt++]=i;
for(int j=0;primes[j]<=n/i;j++)
{
st[primes[j]*i]=true;
if(i%primes[j]==0) break;
}
}
//数组含义同上
二 约数
1 试除法求约数 O(sqrt(n))
vector<int> get_divisors(int n)
{
vector<int> res;
for(int i=1;i<=n/i;i++)
{
if(n%i==0) {
res.push_back(i);
if(i!=n/i) res.push_back(n/i);
}
}
sort(res.begin(),res.end()); //排序
return res;
}
2 约数个数
tip:int 范围内约数最多的数的个数为1536,那个数为 1745944200
N=...... 则N的约数个数为:
(a1+1)(a2+1)(a3+1).......(am+1) 乘法原理
typedef long long ll;
const int mod=1e9+7;
int main()
{
int t;
cin>>t;
unordered_map<int, int> primes; //哈希表存pi和ai
while(t--)
{
int n;
cin>>n;
for(int i=2;i<=n/i;i++)
while(n%i==0)
{
n/=i;
primes[i]++;
}
if(n>1) primes[n]++; //大于sqrt(n)的因子
}
ll res=1;
for(auto prime:primes) res=res*(prime.second+1)%mod;
cout<<res<<"\n";
return 0;
}
3 约数之和
N=...... 则N的约数之和为:
(++....+)(++....+).....(++.....+)
const int mod=1e9+7;
typedef long long ll;
int main()
{
int n;
cin>>n;
unordered_map<int,int> primes;
while(n--)
{
int x;
cin>>x;
for(int i=2;i<=x/i;i++)
while(x%i==0)
{
x/=i;
primes[i]++;
}
if(x>1) primes[x]++;
}
ll res=1;
for(auto prime:primes)
{
int p=prime.first,a=prime.second;
ll t=1;
while(a--) t=(p*t+1)%mod; //求pn^0+pn^1+...+pn^an
res=res*t%mod;
}
cout<<res;
return 0;
}