反素数和素数表

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反素数和素数表相关的知识,希望对你有一定的参考价值。

素数表

2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 , 31 , 37 , 41 , 43 , 47 , 53 , 59 , 61 … \\large 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61\\dots 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61

乘到 29 29 29(一共10项) ,乘积约为 6.47 × 1 0 9 6.47\\times 10^9 6.47×109 i n t int int

乘到 53 53 53(一共16项),乘积约为 3.26 × 1 0 19 3.26\\times 10^{19} 3.26×1019 l o n g   l o n g long \\ long long long

反素数

反素数的性质:

  • 是从最小的质因数 2 2 2开始的连续质数乘积
  • x = p 1 k 1 p 2 k 2 … p m k m , k 1 ≥ k 2 ≥ k 3 ⋯ ≥ k m \\large x=p_1^{k_1}p_2^{k_2}\\dots p_m^{km},k_1\\ge k_2\\ge k_3\\dots\\ge k_m x=p1k1p2k2pmkm,k1k2k3km

1. d ( x ) = n d(x)=n d(x)=n的最小 x x x

根据质因数分解定理,考虑如何构造 x x x

采用搜索+剪枝。

image-20210716095052410

int p[20]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
ll ans=1e18;
int mx=15,n;
void dfs(ll x,int cnt,int dep,int up){
	if(ans>x&&cnt==n) ans=x;
	if(cnt>=n||dep>=mx) return;
	for(int i=1;i<=up;i++){
		if(x>ans/p[dep]||cnt*(i+1)>n) return;
		x*=p[dep];
		if(n%(cnt*(i+1))==0) dfs(x,cnt*(i+1),dep+1,i);
	}
}
int main(){
	scanf("%d",&n);
	dfs(1,1,0,60);
	printf("%lld\\n",ans);
	return 0;
}

2.求 m a x {   d ( i )   } , i ∈ [ 1 , n ] \\large max\\{\\ d(i)\\ \\},i\\in[1,n] max{ d(i) },i[1,n],且 i i i尽可能小。

与上面方法同理。

int p[20]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
ll ans;
int mx=15,tot;
ll n;
void dfs(ll x,int cnt,int dep,int up){
	if(tot<cnt||tot==cnt&&x<ans) ans=x,tot=cnt;
	if(dep>=mx) return;
	for(int i=1;i<=up;i++){
		if(x>n/p[dep]) return;
		x*=p[dep];
		dfs(x,cnt*(i+1),dep+1,i);
	}
}
int main(){
	int t;scanf("%d",&t);
	while(t--){
	scanf("%lld",&n);ans=1e18,tot=0;
	dfs(1,1,0,60);
	printf("%lld %lld\\n",ans,tot);
	}
	return 0;
}

P1463 [POI2002][HAOI2007]反素数

上题的弱化版

// Problem: P1463 [POI2002][HAOI2007]反素数
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1463
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-07-16 11:12:57
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
ll ans,tot;
ll n;
int p[]={2,3,5,7,11,13,17,19,23,29};
void dfs(ll x,int c,int dep,int up){
	if(tot<c||tot==c&&x<ans) ans=x,tot=c;
	if(dep>=10) return;
	for(int  i=1;i<=up;i++){
		if(x>n/p[dep]) return;
		x*=p[dep];
		dfs(x,c*(i+1),dep+1,i);
	}
}
int main(){
	scanf("%lld",&n);
	dfs(1,1,0,30);
	printf("%lld\\n",ans);
	return 0;
}

P1574 超级数

在问题2的基础上,多组询问 q ≤ 1 0 5 q\\le 10^5 q105

因为询问较多,实际上 [ 1 , 1 0 18 ] [1,10^{18}] [1,1018]之间的反素数是很少的,只有 155 155 155个。

因为可以先与出来,然后再每次二分查找。

int p[20]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
ll ans;
int mx=15,tot;
ll n;
void dfs(ll x,int cnt,int dep,int up){
	if(tot<cnt||tot==cnt&&x<ans) ans=x,tot=cnt;
	if(dep>=mx) return;
	for(int i=1;i<=up;i++){
		if(x>n/p[dep]) return;
		x*=p[dep];
		dfs(x,cnt*(i+1),dep+1,i);
	}
}
ll a[N];
ll b[N];
int id;
int main(){
	int m;
	scanf("%d",&m);
	for(int i=1;i<=m;i++) scanf("%lld",&a[i]),n=max(n,a[i]);
	n=1e18;
	while(n>1){
		ans=1e18,tot=0;
		dfs(1,1,0,60);
		b[++id]=ans;
		n=ans-1;
	}
	sort(b+1,b+id+1);
	for(int i=1;i<=m;i++){
		int x=upper_bound(b+1,b+id+1,a[i])-b-1;
		printf("%lld\\n",b[x]);
	}
	return 0;
}

3.区间 [ l , r ] [l,r] [l,r]的反素数

改为枚举不同的质数。

维护当前已经得到的因子数 f r o m from from,当前枚举的质数

以上是关于反素数和素数表的主要内容,如果未能解决你的问题,请参考以下文章

数论——素数和反素数

zoj 1562 反素数 附上个人对反素数性质的证明

反素数

反素数

p1186反素数(模板题)

反素数 -- 数学