您的位置:首页 > 其它

素数--筛选法打表,快速幂,欧拉函数,gcd

2017-10-01 12:22 429 查看
素数筛选法打表

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int M=1e6;
int check[M+50];
int prime[M+50];
int len=0;
void init()
{
int i,j;
for(i=2; i*i<=M; i++)
{
if(!check[i])
{
for(j=i*i; j<M; j+=i)
check[j]=1;//1代表非素数,0代表素数
}
}
check[1]=1;
for(i=1; i<=M; i++)
{
if(!check[i])
{
prime[++len]=i;
}
}
}
int main()
{
init();
int n;
cin>>n;//输出前n个素数
for(int i=1; i<=n; i++)
cout<<prime[i]<<endl;
}


快速幂取余

1

#include<iostream>
using namespace std;
int main()
{
int i,j,k;
int a,b,c,ans=1;
cin>>a>>b>>c;
a=a%c;
while(b)
{
if(b%2==1)
ans=a*ans%c;
b/=2;
a=a*a%c;
}
cout<<ans%c<<endl;
}


2

#include<iostream>
using namespace std;
int main()
{
int i,j,k;
int a,b,c,ans=1;
cin>>a>>b>>c;
a=a%c;
while(b)
{
if(b&1)
ans=a*ans%c;
a=a*a%c;
b>>=1;
}
cout<<ans%c<<endl;
}


欧拉函数

#include<iostream>
using namespace std;
int euler(int n)
{
int ans=n,a=n;
for(int i=2;i*i<=a;i++)
{
if(a%i==0)
{
ans=ans/i*(i-1);
while(a%i==0)
a/=i;
}
}
if(a>1)
ans=ans/a*(a-1);
return ans;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int x;
cin>>x;
cout<<euler(x)<<endl;
}
}


这两天在网上刚发现了一个欧拉筛选法,时间复杂度达到线性,很强!

没看懂,去大牛的博客里把模板copy过来用下~

//check数组里为0的代表素数,prime数组为素数表
#include<iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN=1e5;
const int MAXL=1e6;
int prime[MAXN+50];
bool check[MAXL+50];
int main()
{
int n, len;
memset(check, 0, sizeof(check));
len = 0;
for (int i = 2; i <= MAXL; i++)
{
if (!check[i])
prime[len++] = i;
for (int j = 0; j < len; j++)
{
if (i*prime[j] > MAXL)
break; // 过大的时候跳出
check[i*prime[j]] = 1;
if ((i%prime[j]) == 0) // 如果i是一个合数,而且i % prime[j] == 0
break;
}
}
check[1]=1;
while (~scanf("%d", &n))
{
for (int i = 1; i <=n; i++)
{
if(!check[i])
cout<<i<<endl;
}
}
}


辗转相除法(gcd)

#include<iostream>
using namespace std;
long long int gcd(int m,int n)
{
if(n==0)
return m;
return gcd(n,m%n);
}
int main()
{
long long int m,n;
while(cin>>m>>n)
{
cout<<gcd(m,n)<<endl;
}
}


扩展欧几里得

LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(!b)
{
x=1;
y=0;
return a;
}
LL ans=exgcd(b,a%b,x,y);
LL temp=x;
x=y;
y=temp-a/b*y;
return ans;
}


乘法逆元

int extgcd(int a, int b, int& x, int& y)
{
int d = a;
if(b != 0){
d = extgcd(b, a % b, y, x);
y -= (a / b) * x;
}else {
x = 1;
y = 0;
}
return d;
}
int mod_inverse(int a, int m)
{
int x, y;
extgcd(a, m, x, y);
return (m + x % m) % m;
}


逆元打表

const int mod = 1000000009;
const int maxn = 10005;
int inv[maxn];
inv[1] = 1;
for(int i = 2; i < 10000; i++)
inv[i] = inv[mod % i] * (mod - mod / i) % mod;


阶乘逆元打表

inv[maxn]=mod_pow(fac[maxn],mod-2);
for(ll i=maxn-1;i>=0;i--)
inv[i]=(inv[i+1]*(i+1))%mod;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: