UVA10200-Prime Time/HDU2161-Primes,例题讲解,牛逼的费马小定理和欧拉函数判素数。
此题极坑(本菜太弱),鉴定完毕,9遍过。
题意:很简单的求一个区间[a,b]内满足i*i+i+41(i>=a&&i<=b,0<=a<=b<=10000.)是素数的数有多个,求出百分比。
思路:直接裸判就行了(竟然不超时),但结果要加上1e-8(are you kidding me?)。
下面来说说我怎么跪了,开始也是直接裸判,我算的时间复杂度会超时,果然超时了。后来打个素数表对某些数特判一些,但表最多打1e7,可是数据可以达到1e8,还是超时了。后来又直接把1e4内的素数全部筛出来,一个个判,果断超时。没办法了,只能考虑其他方法了。想到kuangbin模板上有一个Miller_Rabin素数测试,我猜可能是考察这部分知识,我对这个还不熟,于是由又去看了看,结果发现其实这个算法依据的就是费马小定理。我瞬间明白了,依据费马小定理直接用快速幂判断,时间复杂度不高,但结果居然WA了,,我看模板上说的是可能存在伪素数,但WA的结果不得不让我相信(其实是结果没加1e-8)。
由费马小定理:如果p是一个素数,那么任意整数a的euler(p)与1模p同余,也就是模p等于1。那么可以依据这个:如果一个任意数的x-1模x与1同余那么可以判断x是否为素数(kuangbin模板随机素数测试不部分)。虽然没有找到证明,但我觉得前辈是可信的,但这种方法WA了。
于是我又换了一种思路:我们知道一个素数p的欧拉函数(比这个数小并且与这个数互质的的个数)是p-1,那么是否可以用判断一个数p的欧拉函数是否为p-1来判断p是否为素数呢,当然也没有找到相关证明。但我觉得这个逆推的过程与上面依据费马小定理逆推应该差不多。于是用这个方法试了试,,超时。。。。(are you kidding me?)欧拉函数要比快速幂更优啊。
以上两种思路因为没有可靠的证明,于是我和正在去往宁波路上的黄学长交流了一下,也没有得出什么可靠的结果,但彼此互相鼓励了一下,希望他们国赛有个好的发挥吧。没办法,看起来一个很水的题居然搞了,搜了一下题解发现居然就是坑爹的裸判就行了,但网上的方法是把结果打个表,查询方便点。后来把所有的方法都试过之后我才发现原来超时是由于多组测试数据。。。要打表才能过。但以上提到的方法全试了试,全部过了,这让我很兴奋。这是一个新的发现,从来没想过除了开方裸判或者筛法打表还有什么其他的方法来判素数。学了数论之后才发现还可以用牛逼的费马小定理和欧拉函数。
但由于怕结果没有可靠性,又找了个裸素数的题试了试,还是过了,这已经足够证明用欧拉函数或者费马小定理+快速幂判素数的可靠性了。
下面给出几个例题与AC代码:
UVA 10200 - Prime Time
①费马小定理+快速幂:
const int N=1e4+10;
int n,m,len=0,a[N],b[N];
int judge(ll x)
{
ll a=2,b=x-1,res=1;
while(b)
{
if(b&1) res=res*a%x;
a=a*a%x;
b=b>>1;
}
return res==1;
}
int get_ans()
{
int ans=0;
for(int i=n; i<=m; i++)
{
ll x=i*i+i+41;
if(judge(x)) ans++;
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int ans=get_ans();
printf("%.2f\n",ans*1.0/(m-n+1)*100+1e-8);//结果一定要加1e-8,原来中间WA的两次就是没加,但至今不造为什么。
}
return 0;
}
②裸判:
int n,m,sum[N];
int judge(int x)
{
for(int i=2; i*i<=x; i++)
if(x%i==0) return 0;
return 1;
}
void get_ans()
{
memset(sum,0,sizeof(sum));
for(int i=0; i<=1e4; i++)
{
int x=i*i+i+41;
if(judge(x)) sum[i]=1;
}
}
int main()
{
get_ans();
while(~scanf("%d%d",&n,&m))
{
int ans=0;
for(int i=n;i<=m;i++)
ans+=sum[i];
// printf("%d\n",ans);
printf("%.2f\n",ans*1.0/(m-n+1)*100+1e-8);
}
return 0;
}
③欧拉函数的可以自己试试,代码略。
HDU
2161 Primes
裸素数判定,筛法打表想怎么做就怎么做,但这里主要介绍用欧拉函数或费马小定理+快速幂法。
①欧拉函数法:
int euler(int x)
{
int ans=x,xx=x;
for(int i=2;i*i<=x;i++)
{
if(x%i==0)
{
ans-=ans/i;
while(x%i==0) x/=i;
}
}
if(x>1) ans-=ans/x;
return ans==xx-1;
}
int main()
{
int n,t=1;
while(~scanf("%d",&n)&&n>0)
{
printf("%d: ",t++);
if(euler(n)&&n!=2)
printf("yes\n");
else printf("no\n");
}
return 0;
}
②费马小定理+快速幂法:这个开始WA了一发,聪明的你知道用这种方法要注意什么吗?答案在下面。
int fm_fast(int x)
{
int a=2,b=x-1,res=1;
while(b)
{
if(b&1) res=res*a%x;
a=a*a%x;
b=b>>1;
}
return res==1;
}
int main()
{
int n,t=1;
while(~scanf("%d",&n)&&n>0)
{
printf("%d: ",t++);
if(fm_fast(n)&&n>2)//这里开始是n!=2,测样例的时候没看清,原来如果n为1也算,所以要n>2。这坑蛮有意思。
printf("yes\n");
else printf("no\n");
}
return 0;
}
一晚上没搞出什么,但这个发现让我惊喜不已,可能早有别的大牛研究出来了,但毕竟这是自己总结发现的,再次领略到数学的魅力精髓。
UVA10200-Prime Time/HDU2161-Primes,例题讲解,牛逼的费马小定理和欧拉函数判素数。的更多相关文章
- 牛客训练四:Applese 涂颜色(费马小定理+快速幂)
题目链接:传送门 思路: 考虑每一列有2种颜色,总共有n行,每一行的第一个格确定颜色,由于左右颜色不相同,后面的行就确定了. 所以总共有2^n中结果. 由于n太大,所以要用到费马小定理a^n%mod= ...
- 牛客Wannafly挑战赛13-BJxc军训-费马小定理、分式取模、快速幂
参考:https://blog.csdn.net/qq_40513946/article/details/79839320 传送门:https://www.nowcoder.com/acm/conte ...
- 2020牛客寒假算法基础集训营1 J. 缪斯的影响力 (矩阵快速幂/费马小定理降幂)
https://ac.nowcoder.com/acm/problem/200658 f(n) = f(n-1) * f(n-2) * ab ,f的第一项是x,第二项是y. 试着推出第三项是x·y·a ...
- POJ2154 Color【 polya定理+欧拉函数优化】(三个例题)
由于这是第一天去实现polya题,所以由易到难,先来个铺垫题(假设读者是看过课件的,不然可能会对有些“显然”的地方会看不懂): 一:POJ1286 Necklace of Beads :有三种颜色,问 ...
- bzoj4802 欧拉函数(附Millar-Rabin和Pollard-Rho讲解)
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4802 [题解] 参考:http://www.matrix67.com/blog/archiv ...
- 牛客小白月赛12 D 月月给华华出题 (欧拉函数,数论,线筛)
链接:https://ac.nowcoder.com/acm/contest/392/D 来源:牛客网 月月给华华出题 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 131072K, ...
- 2018牛客网暑期ACM多校训练营(第三场) H - Diff-prime Pairs - [欧拉筛法求素数]
题目链接:https://www.nowcoder.com/acm/contest/141/H 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...
- 欧拉函数(汇总&例题)
定义 欧拉函数 $\varphi(n)$表示小于等于$n$的正整数中与$n$互质的数的数目. 性质 1.积性函数(证明). 2.$\varphi(1)=1$(显然) 3.对于质数$n$,$\varph ...
- 牛客OI测试赛 F 子序列 组合数学 欧拉降幂公式模板
链接:https://www.nowcoder.com/acm/contest/181/F来源:牛客网 题目描述 给出一个长度为n的序列,你需要计算出所有长度为k的子序列中,除最大最小数之外所有数的乘 ...
随机推荐
- 494 Target Sum 目标和
给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S.现在你有两个符号 + 和 -.对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面.返回可以使最终数组和为 ...
- NFS与AutoNFS实例
NFS概述: NFS,是Network File System的简写,即网络文件系统.网络文件系统是FreeBSD支持的文件系统中的一种,也被称为NFS. NFS允许一个系统在网络上与他人共享目录和文 ...
- Andriod 简介
Andriod系统采用分层架构,分为4层: 应用程序层(Applications) 包含所有安装在手机上的应用程序(包括系统自带的程序) 应用程序框架层(Application Framework) ...
- Spring-bean(零)
内容提要:红为1,黄2,绿3 -----配置形式:基于xml文件的方式:基于注解的方式 -----Bean的配置方式:通过全类名(反射),通过工厂方法(静态工厂方法&实例工厂方法),Facto ...
- php中include_path配置
在php.ini中可配置include_path来达到在任何文件中都可以直接引入该目录下文件 include_path = ".:/usr/share/php:/var/www/phpxwl ...
- loadrunner11报错:Error -27780
LR回放https协议脚本失败:[GENERAL_MSG_CAT_SSL_ERROR]connect to host "XXX" failed:[10054] Connection ...
- Linux OpenGL 实践篇-10-framebuffer
在之前的实践中我们都是在当前的窗口中渲染,即使用的缓存都是由glutCreateWindow时创建的缓存,我们可称之为默认缓存.它是唯一一个可以被图形服务器的显示系统识别的帧缓存,我们在屏幕上看到的只 ...
- python调用脚本或shell的方式
python调用脚本或shell有下面三种方式: os.system()特点:(1)可以调用脚本.(2)可以判断是否正确执行.(3)满足不了标准输出 && 错误 commands模块特 ...
- (转)SpringMVC学习(九)——SpringMVC中实现文件上传
http://blog.csdn.net/yerenyuan_pku/article/details/72511975 这一篇博文主要来总结下SpringMVC中实现文件上传的步骤.但这里我只讲单个文 ...
- Matlab 图像转极坐标系
实心圆环 imgVP1=flip(imgVP1,1); % 水平翻转 polarVP1=polarVolinPlot(imgVP1); % 调用函数空心圆环 [m,n,~]=size(imgVP2) ...