1. 程式人生 > >codeforces 446E E. Divisors(數論+暴力)

codeforces 446E E. Divisors(數論+暴力)

題目連結:

題目大意:

給出一個x,k,每次操作都會將x分解因數,得到新的序列,然後每次再分解序列中的每一個數,按照每一個數分解因數從小到大排,整體順序不做調整。

題目分析:

因為x是10^12以內的數,我們可以nxlog(n)105個答案,就是對於每個因數遞迴的分解到1,然後輸出答案,達到要求的答案數停止,或者不可以再分解了停止,第二種的複雜度是O(nlog2n),O(105logn)

AC程式碼:

#include <iostream>
#include <cstdio>
#include <algorithm> #include <cstring> #include <vector> using namespace std; typedef long long LL; LL x,k; vector<LL> ans,temp; void init ( ) { ans.clear(); temp.clear(); for ( LL i = 1 ; i*i <= x ; i++ ) { if ( x%i ) continue; temp.push_back ( i ); LL y = x/i; if
( y == i ) continue; temp.push_back ( y ); } sort ( temp.begin() , temp.end() ); } void dfs ( LL x , LL n ) { if ( n == 0 || x == 1 ) { ans.push_back( x ); return; } for ( int i = 0 ; i < temp.size() ; i++ ) { LL tt = temp[i]; if
( tt > x ) break; //cout << tt << endl; if ( x%tt ) continue; dfs ( tt , n-1LL ); if ( ans.size() >= 100000 ) return; } } int main ( ) { while ( ~scanf ( "%lld%lld" , &x , &k ) ) { init(); //cout << temp.size() << endl; dfs ( x , k ); //cout << ans.size() << endl; int lim = 1e5; lim = min ( (int)ans.size() , lim ); for ( int i = 0 ; i < lim ; i++ ) printf ( "%lld " , ans[i] ); puts (""); } }