BZOJ 1053: [HAOI2007]反素數ant【約數】【質因數分解】

傳送門
1~N 中最大的反質數,就是1~N中約數個數最多的數中最小的一個.因爲如果不是最小的那一個,必然會出現g(x)==g(i)
1~N中任何數的不同質因子都不會超過10個,因爲235711131719232931>21092∗3∗5∗7∗11∗13∗17∗19∗23∗29∗31>2∗10^9,且所有質因數的指數總和不超過30,因爲231>21092^{31}>2∗10^9.

使用DFS,嘗試確定前十個質數的指數,然後滿足指數單調遞減,總乘積不超過N,且同時記錄約數的個數
code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define gc getchar

inline int read(){
	int res=0,f=1;
	char ch=gc(); 
	while(!isdigit(ch)) f^=ch=='-',ch=gc();
	while(isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=gc();
	return f?res:-res;
} 

const int mod=998244353;
inline int add(int a,int b){return (a+=b)>mod?a-=mod:a;}
inline int dec(int a,int b) {a-=b;return a+(a>>31&mod);}
inline int mul(int a,int b){ll r=1ll*a*b; return r>=mod?r%mod:r;}
inline void Add(int &a,int b){a=add(a,b);}
inline void Dec(int &a,int b){a=dec(a,b);}
inline void Mul(int &a,int b){a=mul(a,b);}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))if(b&1)Mul(res,a);return res;}

int prime[11]={0,2,3,5,7,11,13,17,19,23,29};
int cnt[11];
int maxn=0,ans=1;
ll n;
void dfs(int u,ll num,int tot){
	if(u==11) {
		if(tot>maxn||(tot==maxn&&ans>num)){
			maxn=tot;ans=num;
		}
		return ;
	}
    for (int i=0;i<=cnt[u-1];i++){
        if (num>n) return;
        cnt[u]=i;
        dfs(u+1,num,tot*(i+1));
        num*=prime[u];
    }
	
} 

int main(){
	n=read();
	cnt[0]=2e9;
	dfs(1,1,1);
	cout<<ans<<endl;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章