思路讲解
ABC-383-D - 9 Divisors
其实这个约数个数定理是显然的
你想p1的指数有0 ~ e 1 0~e_1 0 ~ e 1 也就是e 1 + 1 e_1+1 e 1 + 1 种选择,同理,每种都有e k + 1 e_k+1 e k + 1 种选择
那么根据乘法原理,约束个数也就是 d ( n ) = ( e 1 + 1 ) ( e 2 + 1 ) … ( e k + 1 ) d(n)=(e_1+1)(e_2+1)…(e_k+1) d ( n ) = ( e 1 + 1 ) ( e 2 + 1 ) … ( e k + 1 )
当然喽,只有素因子可以这么玩,非素因子这么玩可能会有重复
当然这道题目关键点不在上面。
N = p 1 e 1 p 2 e 2 N=p_1^{e_1}p_2^{e_2} N = p 1 e 1 p 2 e 2 由题意可得,e1为偶数,e2也为偶数。所以其实400数要求是完全平方数 ,而且是只由两个素因子构成。那么其实也就是要求平方数由两个素因子组成。
哈哈,其实这种也是有点套路,一般来说这种都是直接枚举素因子的
我们用埃氏筛筛出所有1e6以内的素数,存储在primes中。然后就枚举就完了。
枚举代码
1 2 3 4 5 6 7 8 9 10 11 12 13 for (int i=0 ;i<primes.size ();++i){ ll p=primes[i]; for (ll j=p;j<=MAXN-10 ;j*=p){ for (int k=i+1 ;k<primes.size ();++k){ ll pk=primes[k]; if (pk*j>MAXN-10 ) break ; for (ll p_k=pk;p_k<=MAXN-10 ;p_k*=pk){ if (p_k*j>MAXN-10 ) break ; fitNum.pb (p_k*j); } } } }
AC代码
源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 #include <bits/stdc++.h> #define FOR(i, a, b) for (int i = (a); i <= (b); ++i) #define ROF(i, a, b) for (int i = (a); i >= (b); --i) #define all(x) x.begin(),x.end() #define CLR(i,a) memset(i,a,sizeof(i)) #define fi first #define se second #define pb push_back #define SZ(a) ((int) a.size()) using namespace std;typedef long long ll;typedef unsigned long long ull;typedef __int128 i128;typedef pair<ll,ll> pll;typedef array<ll,3> arr;typedef double DB;typedef pair<DB,DB> pdd;typedef pair<ll,bool > plb;constexpr ll MAXN=static_cast <ll>(1e6 )+10 ,INF=static_cast <ll>(5e18 )+3 ;ll N,M,T; bool isPrime[MAXN];vector<ll> primes; vector<ll> fitNum; inline void solve () { cin>>N; ll sqN=sqrtl (N); ll sqAns=*prev (upper_bound (all (fitNum),sqN)); cout<<sqAns*sqAns<<"\n" ; } int main () { ios::sync_with_stdio (false ); cin.tie (0 );cout.tie (0 ); for (int i=2 ;i<=MAXN-10 ;++i){ isPrime[i]=true ; } for (int i=2 ;i*i<=MAXN-10 ;++i){ if (isPrime[i]){ for (int j=2 *i;j<=MAXN-10 ;j+=i){ isPrime[j]=false ; } } } for (int i=2 ;i<=MAXN-10 ;++i){ if (isPrime[i]) primes.pb (i); } for (int i=0 ;i<primes.size ();++i){ ll p=primes[i]; for (ll j=p;j<=MAXN-10 ;j*=p){ for (int k=i+1 ;k<primes.size ();++k){ ll pk=primes[k]; if (pk*j>MAXN-10 ) break ; for (ll p_k=pk;p_k<=MAXN-10 ;p_k*=pk){ if (p_k*j>MAXN-10 ) break ; fitNum.pb (p_k*j); } } } } sort (all (fitNum)); cin>>T; while (T--){ solve (); } return 0 ; }
心路历程(WA,TLE,MLE……)
这个ll是非常需要的,写成int以后就TLE了,可能是因为溢出了。
1 2 3 4 5 6 7 8 9 10 11 12 13 for (int i=0 ;i<primes.size ();++i){ ll p=primes[i]; for (ll j=p;j<=MAXN-10 ;j*=p){ for (int k=i+1 ;k<primes.size ();++k){ ll pk=primes[k]; if (pk*j>MAXN-10 ) break ; for (ll p_k=pk;p_k<=MAXN-10 ;p_k*=pk){ if (p_k*j>MAXN-10 ) break ; fitNum.pb (p_k*j); } } } }