这波就不打题号了
[POI2001][HAOI2007]反素数
https://www.luogu.com.cn/problem/P1463https://www.luogu.com.cn/problem/P1463
题解:
开始拿到这道题的时候毫无头绪,然而旁边两人都秒了,这波直接心态炸掉,无奈自己自己没做过TAT,好吧,其实这道题是可以打表的,而且并不是很慢
打表程序:
#include<cstdio>
#include<algorithm>
using namespace std;
int vis[1000100],prime[1000100];
int cnt;
inline long long getsum(long long x)
{
long long now,cn,ret=1;
for(int i=1;i<=13;i++){
now=x;
cn=0;
while(now%prime[i]==0){
cn++;
now/=prime[i];
}
ret*=(cn+1);
}
return ret;
}
int main(void)
{
for(int i=2;i<=1000010;i++){
if(vis[i]==0){
vis[i]=i;
prime[++cnt]=i;
}
for(int j=1;j<=cnt && i*prime[j]<=1000010;j++){
if(vis[i*prime[j]]<prime[j] && vis[i*prime[j]]!=0)break;
vis[i*prime[j]]=prime[j];
}
}
long long maxn=0;
for(long long i=1;i<=2000000000;i++){
long long kk=getsum(i);
if(maxn<kk)printf("%lld,",i);
maxn=max(maxn,kk);
}
}
打表标程:
#include<cstdio>
using namespace std;
int ans[501]={0,1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,5040,7560,10080,15120,20160,25200,27720,45360,50400,55440,83160,110880,166320,221760,277200,332640,498960,554400,665280,720720,1081080,1441440,2162160,2882880,3603600,4324320,6486480,7207200,8648640,10810800,14414400,17297280,21621600,32432400,36756720,43243200,61261200,73513440,110270160,122522400,147026880,183783600,245044800,294053760,367567200,551350800,698377680,735134400,1102701600,1396755360,2001000000};
int n;
int main(void)
{
scanf("%d",&n);
for(int i=1;i<=500;i++){
if(ans[i]>n){
printf("%d",ans[i-1]);
return 0;
}
}
}
好吧蒙混过关的方法讲了,该说正经点的了
关于正解:
设,则显然
设严格递增,并且
也算在内,则如果
并且
,那么显然这个数不可能是反素数,因为交换
会更好,这样以来,交换前乘积和交换后乘积的因数个数相同,但是前者的积比后者的积大,所以相比之下后者会更加优秀。
所以对于一个反素数,当它的