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的子序列中,除最大最小数之外所有数的乘 ...
随机推荐
- h5-16-SVG 与 HTML5 的 canvas 各自特点
1. Canvas是使用JavaScript程序绘图(动态生成),SVG是使用XML文档描述来绘图.2.SVG更适合用来做动态交互,而且SVG绘图很容易编辑,只需要增加或移除相应的元素就可以了.同时S ...
- iOS常用第三方库 -转
转自 http://www.cnblogs.com/jukaiit/p/4956419.html 1.AFNetworking 轻量级的通讯类库,使用非常简单. 下载地址:https://github ...
- rac 添加 资源
10g : 自动化.监控.os,存储,底成,网络,规范
- C/C++程序计时函数gettimeofday的使用
linux 环境下 用 clock_t发现不准. 换用 //头文件 #include <sys/time.h> //使用timeval start, end; gettimeofday ...
- Backbone学习记录(7)
事件委托 <form> <input type="text" class="txt"> <input type="but ...
- Ionic之数据绑定ng-model
ionic 完美的融合下一代移动框架,ionic 基于Angular语法,支持 Angularjs 的特性.但是我在开发的时候,遇到了坑.因为之后用的就是angularjs,so 理所当然的以为代码应 ...
- [转]在WIN7下安装运行mongodb
本文转自:http://www.cnblogs.com/snake-hand/p/3172376.html 1).下载MongoDB http://downloads.mongodb.org/win3 ...
- 使用css3 制作switch开关
使用css3来实现switch开关的效果: html代码: <!--switch开关--><div class="switch-btn"> <inpu ...
- os模块详解2
1.os.getenv('HOME') 读取操作系统环境变量HOME的值. 2.os.environ 返回操作系统所有的环境变量. 3.os.environ.setdefault(‘a’,‘b’) ...
- 自定义Toast的显示位置和显示内容
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...