试除法求约数
题目大意:输出n个数,分别输出这n个数所有的约数
# include <iostream>
# include <algorithm>
# include <vector>
using namespace std;
const int N = 1e5 + 10;
vector<int> solve (int n){
vector<int> a;
// 当i是约数,那么n/i必定也是约数
for (int i = 1; i <= n/i; i ++){
if (n%i == 0){
a.push_back(i);
// 当i!= n/i 把n/i读入
if (n/i != i)
a.push_back(n/i);
}
}
sort (a.begin(),a.end());
return a;
}
int main(){
int n;
cin >> n;
int num;
while (n --){
cin >> num;
auto t = solve(num);
///for(auto x : arr) 遍历方式, x只是将arr里的元素复制下来,改变x不会改变arr的元素
//for(auto &x : arr) x是将arr元素的地址拿出来,改变x会改变arr的元素
for (auto x : t)
printf("%d ",x);
puts("");
}
}
约数的个数
基于算术基本定理
N = (p1x1)(p2x2)(p3x3)…(pkxk)
约数个数=(x1+1)(x2+1)(x3+1)…(xk+1)
注意,这里的p1…pi是指质因子
例子
24=2223=2³3
再用各个质数的指数加一后再相乘即为此数的约数个数,
比如 (3+1)(1+1)=42=8, 即表示24有8个约数。
24的约数:1、2、3、4、6、8、12、24
思路就是先把原数分解为质因数,最后把每一个数的指数累加即可。从a1一直分解到an,由于a的数据过大,此处用哈希表进行存储。
题目:求n个数的乘积的约数个数
因此不能乘起来再求,这里用哈希表存一下质因子和其指数,用相应的公式求解
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
int main(){
int n , x;
unordered_map<int,int> hash;
cin >> n;
while (n --){
cin >> x;
for (int i = 2; i <= x/i; i ++){
while (x%i==0){
hash[i] ++;
x/=i;
}
}
// x最大公约数可能大于sqrt(x),将剩余的质因数读取进去
if (x > 1) hash[x] ++;
}
ll ans = 1;
for (auto i : hash) ans = ans * (1 + i.second) %mod;
cout << ans;
return 0;
}
约数之和
这里的约数个数和约数之和 这两个公式是建立在质因字的前提下
题目:求n个数的乘积的约数之和 同上题一样
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
int main(){
int n,x;
unordered_map<int,int> hash;
cin >> n;
while (n --){
cin >> x;
for (int i = 2; i <= x/i; i ++){
while (x%i == 0){
x /= i;
hash[i] ++;
}
}
if (x > 1) hash[x] ++;
}
ll ans = 1;
for (auto i: hash){
ll a = i.first;
ll b = i.second;
ll t= 1;
while (b --){
t = (t*a + 1) % mod;
}
ans = ans * t % mod;
}
cout << ans;
return 0;
}
完全平方数
题目: acwing3491
题意 : 输出一个数a, 让你求出一个最小的数b,使得a*b是某数的平方
思路: 求出a的所有质因数及其质因数的指数,那么ans就是指数为奇数的质因数的乘积
代码
# include <iostream>
# include <unordered_map>
# include <string>
# include <algorithm>
using namespace std;
typedef long long ll;
int main(){
ll n;
ll ans = 1;
cin >> n;
unordered_map<ll,ll> hash;
for (ll i = 2; i <= n/i; i ++){
while (n%i == 0){
n/=i;
hash[i] ++;
}
}
if(n > 1) hash[n] ++;
for (auto i : hash){
if (i.second%2)
ans *= i.first;
}
cout << ans;
return 0;
}