先是素数筛
据说这个叫做欧拉线性筛, 差不多半年以前我曾经被一道有关素数的题目卡住了时限, 后来网上随便找了一个素数筛模板(捂脸逃), 过了, 这个以前的一篇博客也提到过了, 就是注释了我认为"非常精妙"的那个素数筛. 不过当时抄的那个在某些地方不是很好用, 所以又上网找了了一下其他的模板进行借鉴, 稍微增添了一点东西.
const int maxn=1000000;//这里的maxn常数可以自定义
long long prime_number[maxn];//这个不必废话,就是存放最后素数的数组,数组大小看后面给的参数,变量类型自己取舍
bool prime_check[maxn+5];//首先增添的是这个数组, check数组大小取决于你要求到多大的素数
int work_prime(long long int n)//n是你要打表到多大,比如n=10那就只打了2,3,5,7
{//函数返回值为有多少个素数
//来自网上某博文,忘记网址了你打我啊
//感觉很精妙,实话
//不用先筛再遍历记录,时间快了不少
int res,i,j;
res=0;
for (i=2;i<=n;i++)
{
if (!prime_check[i])
prime_number[res++] = i;
for (j=0;j<res&&i*prime_number[j]<=n;j++)
{
prime_check[prime_number[j]*i]=1;
if (i%prime_number[j]==0)
break;
}
}
return res;//返回这个筛有多少个质数,并将质数依次放入prime_number数组中
}
然后就是关于素数筛开多大的问题, 这里给出一些幂次对应最接近的素数的大小和序号, 以供参考.小于 10^1: 7 第4个
小于 10^2: 97 第25个
小于 10^3: 997 第168个
小于 10^4: 9973 第1229个
小于 10^5: 99991 第9592个
小于 10^6: 999983 第78498个
小于 10^7: 9999991 第664579个
小于 10^8: 99999989 第5761455个
小于 10^9: 999999937 第50847534个
然后就是欧拉函数
欧拉函数的意思是求1~n-1中, 与n互质的数的个数
关于公式可以由容斥原理获得, 也可以直接看学长博客(逃
然后原本的代码是这个样子的
long long phi(long long n)
{
long long res=n,i;
for(i=2;i*i<=n;i++)
if(n%i==0)
{
res=res-res/i;
while(n%i==0)
n=n/i;
}
if(n>1)
res=res-res/n;
return res;
}
不过呢, 当我们使用了素数筛的话, 这个就更快了
假设我们已经打完表了, 拥有了一个素数表prime_number[]和里面存有的素数个数prime_num, 那么可以这么写
long long phi(long long n)
{
long long res,i;
res=n;
for(i=0;prime_number[i]*prime_number[i]<=n&&i<prime_num;i++)
//跳出循环条件中的prime_num表示打出来的素数筛的表里面一共有多少个素数, 毕竟不能越界嘛
if(n%prime_number[i]==0)
{
res=res-res/prime_number[i];
while(n%prime_number[i]==0)
n=n/prime_number[i];
}
if(n>1)
res=res-res/n;
return res;
}
在我们需要多次重复求欧拉函数的时候, 打表也是可以的.
void phi(long long phi[],long long maxn)
{//maxn表示你要打到多少
int i,j;
for(i=1;i<=maxn;i++)
phi[i]=i;
for(i=2;i<=maxn;i+=2)
phi[i]/=2;
for(i=3;i<=maxn;i+=2)
if(phi[i]==i)
{
for(j=i;j<=maxn;j+=i)
phi[j]=phi[j]-phi[j]/i;
}
}
然后就是欧拉定理和费马小定理了
欧拉定理的描述: 若a和p互质, 则有 a^phi(p) %p =1
费马小定理的描述: 若a和p互质, 且p是质数, 则有 a^(p-1) %p =1 其实道理很简单, 因为质数p的欧拉函数值就是p-1呀
然后就有了一个有趣的逆元应用 ( a * a^(p-2) )%p =1
换句话说求a对于模p的乘法逆元, p是质数且a和p互质的话, 只要求a^(p-2) %p就行了, 参见快速幂.