快速乘+快速幂+矩阵快速幂+欧拉筛

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;
        }
    }
}
发布了54 篇原创文章 · 获赞 28 · 访问量 7297

猜你喜欢

转载自blog.csdn.net/jiangkun0331/article/details/97820529