素数and约数and反素数
素数、约数、反素数
- 素数
- 判断素数
- 查找一定范围内的所有素数(欧拉筛)
- 练习:质数距离
- 约数
- 概念
- 考点
- 唯一分解定理
- 约数个数
- 约数之和
- 题目:Aladdin and the Flying Carpet
- 反素数
- 定义
- 结论
- 题目
素数
判断素数
素数的判断:试除法
如果自然数n不能被[ 2 ,n\sqrt nn]内所有素数整除,即为素数
(且素数有一个规律:大于4的素数一定在6的倍数的左右,即总是等于6x+1/6x+5)
代码:
bool prime(int n){if(n<=3)return n>1;if(n%6!=1&&n%6!=5)return false;for(int i=5;i*i<=n;i+=6)if(n%i==0||n%(i+2)==0)return false;return true;
}
查找一定范围内的所有素数(欧拉筛)
const ll N=1e6+10;
int prime[N],num;
bool vis[N];
void getprime(int n){memset(vis,false,sizeof(vis));num=0;for(int i=2;i<=n;i++){if(!vis[i])prime[num++]=i;for(int j=0;j<num&&i*prime[j]<=n;j++){vis[i*prime[j]]=true;if(i%prime[j]==0)break;}}
}
练习:质数距离
题目
思路分析:
1.此题查找的范围大,如何缩小质数的查找范围呢?
若一个数x是合数,那么它一定能在[ 2 ,x\sqrt xx]范围内找到至少一个素数能整除x:所以我们在查找素数的时候只需要查找到r\sqrt rr就可以啦
2.查找后怎么将[l,r]范围内的素数找出来呢?
(由于我们没有把[l,r]范围内的所有素数找出来所以不能直接得到所有的素数)
可以先筛掉[l,r]范围内的合数。从每一个素数x,从max(x*2,(l+x-1)/x*x)
开始每次加素数(即素数的倍数)……标记合数,直到素数 * n>r的时候停止,每个素数重复此操作便可把[l,r]范围内所有的合数标记一遍剩下的即素数;
(x为素数)
max(x*2,(l+x-1)/x*x)
解释:
(l+x-1)/x*x
:是为了找到第一个在[l,r]范围内的合数,即⌈lx⌉∗x\lceil \frac{l}{x} \rceil*x⌈xl⌉∗x;
实际上为⌈lx⌉\lceil \frac{l}{x} \rceil⌈xl⌉,由于int为截断整数部分所以公式为如上形式;
x*2
:若⌈lx⌉\lceil \frac{l}{x} \rceil⌈xl⌉为1则应该为x*2
因为x本身为质数,x∗⌈lx⌉=x∗1=xx* \lceil \frac{l}{x} \rceil= x * 1=xx∗⌈xl⌉=x∗1=x 此时把x标记为合数就错了。
为了防止数据太大标记的时候超出数组的内存,我们可以做个小优化:
就是标记的是实际(合数−l-l−l)在后面查找素数的时候记得➕lll就可以啦
完成筛合数的工作就开始存放[l,r]范围内的质数然后遍历相邻质数两两之间的距离即可;
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;const int N=1e6+10;
int prime[N],num;
bool vis[N];void getprime(int n){memset(vis,false,sizeof(vis));num=0;for(int i=2;i<=n;i++){if(!vis[i])prime[num++]=i;for(int j=0;j<num&&i*prime[j]<=n;j++){vis[i*prime[j]]=true;if(i%prime[j]==0)break;}}
}int main(){int l,r;while(~scanf("%d%d",&l,&r)){getprime(sqrt(r));memset(vis,false,sizeof(vis));//[l,r]内的所有合数筛掉 for(int i=0;i<num;i++){ll c=prime[i];for(ll j=max(2*c,(l+c-1)/c*c);j<=r;j+=c){vis[j-l]=true;}}num=0;//存[l,r]范围内的质数for(int i=0;i<=r-l;i++){if(!vis[i]&&i+l>1){prime[num++]=i+l;}} if(num<2){cout<<"There are no adjacent primes."<<endl;}else{int maxx=0,minn=0;for(int i=0;i+1<num;i++){int d=prime[i+1]-prime[i];if(prime[maxx+1]-prime[maxx]<d)maxx=i;if(prime[minn+1]-prime[minn]>d)minn=i;}printf("%d,%d are closest, %d,%d are most distant.\n",prime[minn],prime[minn+1],prime[maxx],prime[maxx+1]);}}return 0;
}
约数
概念
约数,又称因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数,我们就说a能被b整除,或b能整除a。a称为b的倍数,b称为a的约数。(摘自百度百科)
考点
唯一分解定理
唯一分解定理:任意一个大于1的自然数nnn都能被表示成有限个素数的乘积且表示方法是唯一的;整理可以将相同素数的合并;可以得到公式n=P1a1∗P2a2∗…∗Pnann=P_1^{a_1} * P_2^{a_2} * …* P_n^{a_n}n=P1a1∗P2a2∗…∗Pnan
PiP_iPi均为素数且(P1<P2<……<Pn)( P_1 < P_2 < ……<P_n)(P1<P2<……<Pn)
约数个数
n的正约数个数为:(a1+1)∗(a2+1)∗(a3+1)∗…∗(an+1)=∏i=1n(ai+1)({a_1}+1)*({a_2}+1)*({a_3}+1)*…*({a_n}+1)= \prod_{i=1}^{n}({a_i}+1)(a1+1)∗(a2+1)∗(a3+1)∗…∗(an+1)=∏i=1n(ai+1)
约数之和
n的正约数之和:(1+P1+P12+…+P1a1)∗(1+P2+P22+…+P2a2)∗…∗(1+Pm+Pm2+…+Pmam)(1+{P_1}+{P_1}^2+…+{P_1}^{a_1})*(1+{P_2}+{P_2}^2+…+{P_2}^{a_2})*…*(1+{P_m}+{P_m}^2+…+{P_m}^{a_m})(1+P1+P12+…+P1a1)∗(1+P2+P22+…+P2a2)∗…∗(1+Pm+Pm2+…+Pmam)=== ∏i=1n\prod_{i=1}^{n}∏i=1n (∑j=0ai\sum_{j = 0} ^{a_i}∑j=0ai Pij{P_i}^jPij)
题目:Aladdin and the Flying Carpet
题目
一些解释
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;const int N=1e6+10;
int prime[N],num;
bool vis[N];
ll s,d;
void getprime(int n){memset(vis,false,sizeof(vis));num=0;for(int i=2;i<=n;i++){if(!vis[i])prime[num++]=i;for(int j=0;j<num&&i*prime[j]<=n;j++){vis[i*prime[j]]=true;if(i%prime[j]==0)break;}}
}ll find(){ll ans=1,ss=s;if(s/d<d)return 0;for(int i=0;i<num&&prime[i]*prime[i]<=s;i++){int c=0;while(s%prime[i]==0){c++;s/=prime[i];}ans*=(c+1);} if(s>1)ans*=2;//此时还有一个因子可以在原因数情况下选择乘或不乘两种情况,所以乘上2 ans/=2;//这里很好若出现正方形的情况在除以2 的时候亦可以把正方形给消去 for(int i=1;i<d;i++)//暴力除去边长小于d的情况 if(ss%i==0)ans--;return ans;
}int main()
{int t,num=0;cin>>t;getprime(N);while(t--){cin>>s>>d;printf("Case %d: %lld\n",++num,find());} return 0;
}
反素数
定义
对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。
如果某个正整数x满足:g(x)>g(i) 且 0<i<x,则称x为反素数。例如,整数1,2,4,6等都是反素数。(摘自百度百科)
反素数可以理解为:约数相同时的最小数
结论
从中,我们可以得到:
若n为反素数,则一定满足:
n=2t1∗3t2∗5t3∗7t4∗…n=2^{t_1}*3^{t_2}*5^{t_3}*7^{t_4}*…n=2t1∗3t2∗5t3∗7t4∗… 且 t1≥t2≥t3≥t4…{t_1}\geq{t_2}\geq{t_3}\geq{t_4}…t1≥t2≥t3≥t4…
即尽可能让质因子数量多且数值小
题目
题目
分析:
反素数的不同质因子不会超过10个:
2∗3∗5∗7∗11∗13∗17∗19∗23∗29∗31>2∗1092*3*5*7*11*13*17*19*23*29*31>2*10^92∗3∗5∗7∗11∗13∗17∗19∗23∗29∗31>2∗109
反素数所有质因数总和不会超过30:
231>2∗1092^{31}>2*10^9231>2∗109
可以采用dfs暴搜
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;const int N=30;
int prime[N]={2,3,5,7,11,13,17,19,23,29};int n,ans,sum=0;
/*sum:记录最大约数个数pos:待搜索质因子序号last:待搜索质因子指数最大值mul:约数之积s:每轮约数个数
*/
void dfs(int pos,int last,int mul,int s){//更新反素数if(s>sum||(s==sum&&mul<ans)){sum=s;ans=mul;}for(int i=1;i<=last;i++){if((ll)mul*prime[pos]>n)break;mul*=prime[pos];dfs(pos+1,i,mul,s*(i+1));}
}int main()
{cin>>n;dfs(0,30,1,1);cout<<ans<<endl;return 0;
}
素数and约数and反素数相关推荐
- zoj 1562 反素数 附上个人对反素数性质的证明
反素数的定义:对于不论什么正整数,其约数个数记为.比如,假设某个正整数满足:对随意的正整 数.都有,那么称为反素数. 从反素数的定义中能够看出两个性质: (1)一个反素数的全部质因子必定是从2開始的连 ...
- 【CodeForces - 27E】Number With The Given Amount Of Divisors (数论,数学,反素数)
题干: Given the number n, find the smallest positive integer which has exactly n divisors. It is guara ...
- 1748. The Most Complex Number/LG的数学计划~~~持续更新ing(反素数求解)
神奇的反素数, 首先定义 g(x) = x的约数个数 而反素数就是对于任意的0 < j < i 有g(j) < g(i)那么就称i为反素数 那么从这个定义中可以发现的是, 反素数一定 ...
- 洛谷P1463 - 反素数
题目描述 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4. 如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数.例如,整数1,2,4,6 ...
- AcWing 198. [HAOI2007] 反素数 约数个数+dfs
题 参考 约数个数:每个质因数的次数+1的乘积. 2e9<2x3x5x7x11x13x17x19x23; 2e9<pow(2,31); last其实是最多扫30次. #include< ...
- HDU 4228 Flooring Tiles 反素数的应用
给你一个数N,找出一个最小的可以拆分成N种乘积表达形式的数x 比如N=2,6可以拆成2x3或者1x6两种,但不是最小的,最小的是4可以拆成1x4,2x2两种 首先可以肯定的是x必然有N*2或者是N*2 ...
- 反素数(luogu 1463)
题目描述 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4. 如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数.例如,整数1,2,4,6 ...
- BZOJ(8) 1053: [HAOI2007]反素数ant
1053: [HAOI2007]反素数ant Time Limit: 10 Sec Memory Limit: 162 MB Submit: 4118 Solved: 2453 [Submit][ ...
- BZOJ 1053 [HAOI2007]反素数ant
53: [HAOI2007]反素数ant Description 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4.如果某个正整数x满足:g(x)>g(i) 0< ...
- bzoj1053: [HAOI2007]反素数ant
51nod有一道类似的题...我至今仍然不会写暴搜!!! #include<cstdio> #include<cstring> #include<iostream> ...
最新文章
- c语言 编程 牛顿迭代,C语言编写牛顿迭代法的跟踪
- 软件测试准备(摘要)
- GIS专家:云GIS带来的最大影响是体系架构
- AVC与H264 区别
- 特别实用的几种SQL语句送给大家,让你的SQL高大上!
- linux系统root用户忘记密码的重置方法
- 【bzoj2219-数论之神】求解x^a==b(%n)-crt推论-原根-指标-BSGS
- sourcetree向github推送代码提示密码错误
- Typora突然开始收费?开源免费的MarkText了解一下
- java的duplicate用法_Java IntBuffer duplicate()用法及代码示例
- 清除浮动(解决高度坍塌的问题)的方法5种
- 搜索插件像百度那样的智能感知效果
- 导航星历的钟差,TGD问题
- Power BI Power Query页面使用python进行数据处理
- 关于MC34063的奇怪问题参考解决方案(mc34063升压失败、输出等于输入,输出电压低于输入)
- comsol如何定义狄利克雷边界_在变分问题中指定边界条件和约束
- Hadoop的两个核心组成
- 笔记一:画笔、笔刷认识
- 世界战争英雄服务器怎么修改,世界战争-英雄 修改版
- ValueError: With n_samples=1, test_size=0.2 and train_size=None, the resulting train set will be