O(1) 快速乘
#include <iostream>
using namespace std;
int main()
{
int a, b;
cin >> a >> b;
cout << a * b << endl;
return 0;
}
防止溢出
时间复杂度为 O(logn)
typedef long long LL;
LL quick_mul(LL a, LL b, LL mod){
LL res = 0;
while(b){
if(b & 1){
res = (res + a) % mod;
}
a = (a + a) % mod;
b >>= 1;
}
return res;
}
更快的方法
通过long double直接算
#include <iostream>
using namespace std;
typedef long long LL;
LL a, b, mod;
LL O1quick_mul(LL a, LL b, LL mod){
LL tmp = LL(a * (long double)b / mod);
return ((a * b - tmp * mod) + mod) % mod;
}
int main()
{
cin >> a >> b >> mod;
cout << O1quick_mul(a, b, mod) << endl;
return 0;
}
快速幂
typedef long long LL;
LL poww(LL a, LL n, LL mod){
LL res = 1;
while(n){
if(n & 1) res = (res * a) % mod;
a = (a * a) % mod;
n >>= 1;
}
return res;
}
矩阵快速幂
例题
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define MOD 1000000009
struct matrix{
ll m[2][2];
};
matrix matrix_multi(matrix a,matrix b){
matrix tmp;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++){
tmp.m[i][j]=0;
for(int k=0;k<2;k++)
tmp.m[i][j]=((tmp.m[i][j])% (MOD) + (a.m[i][k]*b.m[k][j]+MOD)% (MOD)) % (MOD);
}
return tmp;
}
matrix matrix_pow(matrix a,matrix b,ll n){
while(n>0){
if(n&1) b=matrix_multi(a,b);
a=matrix_multi(a,a);
n>>=1;
}
return b;
}
int main(){
matrix a,b,ans;
ll n;
a.m[0][0]=1; a.m[0][1]=0;
a.m[1][0]=1; a.m[1][1]=0;
b.m[0][0]=1; b.m[0][1]=1;
b.m[1][0]=1; b.m[1][1]=0;
while(~scanf("%lld", &n)){
ans=matrix_pow(b,a,n-2);
printf("%lld\n", ans.m[0][0]);
}
return 0;
}
埃氏筛
int isprime[MAXN];
int vis[MAXN];
void Prime(int n)
{
int cnt = 0;
memset(vis, 0, sizeof(vis)); //vis里0是素数,1是合数
vis[0] = 1;
vis[1] = 1;
for (int i = 2; i < n; i++){
if (!vis[i]){
isprime[cnt++] = i; //保存素数
for (int j = i * i; j < n; j += i){
vis[j] = 1; //不是素数
}
}
}
}
欧拉筛
int isprime[MAXN]; //保存素数
int vis[MAXN]; //初始化
void eulerSieve(int n)
{
int cnt = 0;
memset(vis, 0, sizeof(vis)); //0是素数,1是合数
for (int i = 2; i < n; i++){
if (!vis[i])
isprime[cnt++] = i;
for (int j = 0; j < cnt && i * isprime[j] < n; j++){
vis[i * isprime[j]] = 1;
if (i % isprime[j] == 0)
break;
}
}
}