约数
吐槽:
好多定理啊
分解质因数
AcWing 872. 最大公约数
库函数
bits/stdc++.h
__gcd(a,b);
871. 约数之和(O√n +M log M)
细节:
因为ai的范围是 2e9+10
所以 如果使用 On的暴力枚举是必然超过的
借用@Bug-Free一张图
///若d > √n 是 N的约数
///则 N/d <= √n 也是N 的约数
///换言之 约数总是成对出现的(除了完全平方数)
因此因为这个关系
所以y总的代码就把时间复杂度改成O√n +M log M
(M表示的是 约数的个数)
Code:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> get_divisors(int x)
{
vector<int> res;
for (int i = 1; i <= x / i; i ++ )
if (x % i == 0)
{
res.push_back(i);
if (i != x / i) res.push_back(x / i);
}
sort(res.begin(), res.end());
return res;
}
int main()
{
int n;
cin >> n;
while (n -- )
{
int x;
cin >> x;
auto res = get_divisors(x);
for (auto x : res) cout << x << ' ';
cout << endl;
}
return 0;
}
870. 约数个数
原理(感谢 @灰之魔女 ):
Code:
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
const int mod=1e9+7;
int main()
{
int n;
cin>>n;
unordered_map<int,int> primes;//映射函数
while(n--)
{
int x;
scanf("%d",&x);
for(int i=2;i<=x/i;i++)
while(x%i==0)
{
primes[i]++;
x/=i;//方便求得约数的数量
}
if(x>1) primes[x]++;//x的最大公约数可能大于sqrt(x);
}
long long res=1;
for(auto p:primes) res=res*(p.second+1)%mod;//将统计出来的数按照由图中公式所得出来的结论得出答案
printf("%lld\n",res);
return 0;
}
AcWing 871. 约数之和(滚去当板子吧)
原理(真不敢兴趣)
Code:
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <vector>
using namespace std;
typedef long long LL;
const int N = 110, mod = 1e9 + 7;
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 p : primes)
{
LL a = p.first, b = p.second;
LL t = 1;
while (b -- ) t = (t * a + 1) % mod;
res = res * t % mod;
}
cout << res << endl;
return 0;
}