1.筛质数
例题:
给定一个正整数n,请你求出1~n中质数的个数。
输入格式
共一行,包含整数n。
输出格式
共一行,包含一个整数,表示1~n中质数的个数。
数据范围
1≤n≤106
输入样例:
8
输出样例:
4
方法一:埃式筛法
void get_primes1(){
for(int i=2;i<=n;i++){
if(!st[i]){
primes[cnt++]=i;
for(int j=i;j<=n;j+=i) st[j]=true;//可以用质数就把所有的合数都筛掉;
}
}
}
方法二:线性筛法
void get_primes(){
//外层从2~n迭代,因为这毕竟算的是1~n中质数的个数,而不是某个数是不是质数的判定
for(int i=2;i<=n;i++){
if(!st[i]) primes[cnt++]=i;
for(int j=0;primes[j]<=n/i;j++){//primes[j]<=n/i:变形一下得到——primes[j]*i<=n,把大于n的合数都筛了就
//没啥意义了
st[primes[j]*i]=true;//用最小质因子去筛合数
//1)当i%primes[j]!=0时,说明此时遍历到的primes[j]不是i的质因子,那么只可能是此时的primes[j]<i的
//最小质因子,所以primes[j]*i的最小质因子就是primes[j];
//2)当有i%primes[j]==0时,说明i的最小质因子是primes[j],因此primes[j]*i的最小质因子也就应该是
//prime[j],之后接着用st[primes[j+1]*i]=true去筛合数时,就不是用最小质因子去更新了,因为i有最小
//质因子primes[j]<primes[j+1],此时的primes[j+1]不是primes[j+1]*i的最小质因子,此时就应该
//退出循环,避免之后重复进行筛选。
if(i%primes[j]==0) break;
}
}
}
2.约数个数
结论:N为当前需要判断的数,ans为约数个数。
例题
给定n个正整数ai,请你输出这些数的乘积的约数个数,答案对109+7取模。
输入格式
第一行包含整数n。
接下来n行,每行包含一个整数ai。
输出格式
输出一个整数,表示所给正整数的乘积的约数个数,答案需对109+7取模。
数据范围
1≤n≤100,
1≤ai≤2∗109
输入样例:
3
2
6
8
输出样例:
12
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
int main(){
int n,x;
LL ans = 1;
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] ++;
}
for(auto i : hash) ans = ans*(i.second + 1) % mod;
cout << ans;
return 0;
}
3.约数之和
结论:
例题
给定n个正整数ai,请你输出这些数的乘积的约数之和,答案对109+7取模。
输入格式
第一行包含整数n。
接下来n行,每行包含一个整数ai。
输出格式
输出一个整数,表示所给正整数的乘积的约数之和,答案需对109+7取模。
数据范围
1≤n≤100,
1≤ai≤2∗109
输入样例:
3
2
6
8
输出样例:
252
#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
map<int,int> primes;
int n;
int main(){
cin>>n;
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]++;
}
long long res=1;
for(auto x:primes){
int first=x.first;
int second=x.second;
long long t=1;
while(second--) t=(t*first+1)%mod;
res=res*t%mod;
}
cout<<res<<endl;
return 0;
}
4.快速幂
#include<bits/stdc++.h>
using namespace std;
int n;
long long mi(int a,int b,int k){
long long res=1;
while(b){
if(b&1) res=(long long)res*a%k;
b>>=1;
a=(long long)a*a%k;
}
return res;
}
int main(){
scanf("%d",&n);
while(n--){
int a,k,p;//a的k次方对p取余
cin>>a>>k>>p;
cout<<mi(a,k,p)<<endl;;
}
return 0;
}
5.求组合数
递推式:
给定n组询问,每组询问给定两个整数a,b,请你输出Cab mod (109+7)的值
#include<bits/stdc++.h>
using namespace std;
const int N = 2010;
const int MOD = 1e9+7;
int n;
int c[N+1][N+1];
void init(){
for(int i=0;i<N;i++){
for(int j=0;j<=i;j++){
if(!j) c[i][j]=1;
else c[i][j]=(c[i-1][j]+c[i-1][j-1])%MOD;
}
}
}
int main(){
cin>>n;
init();
while(n--){
int a,b;
cin>>a>>b;
cout<<c[a][b]<<endl;
}
return 0;
}