反素数和素数表
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=p1k1p2k2…pmkm,k1≥k2≥k3⋯≥km
1. d ( x ) = n d(x)=n d(x)=n的最小 x x x
根据质因数分解定理,考虑如何构造 x x x。
采用搜索+剪枝。
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 q≤105。
因为询问较多,实际上 [ 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,当前枚举的质数
以上是关于反素数和素数表的主要内容,如果未能解决你的问题,请参考以下文章