問題描述
原題來自 poj 3421
輸入正整數 x,求 x 的大於 1 的因子組成的滿足任意前一項都能整除後一項的序列的最大長度,以及滿足最大長度的序列的個數。
輸入
多組資料,每組資料一行,包含乙個正整數 x。
輸出
對於每組資料,輸出序列的最大長度以及滿足最大長度的序列的個數。
樣例輸入2
3410100
樣例輸出
1 11 12 1
2 24 6
提示
對於全部資料,1≤x≤220。
問題分析
多重集排列計數,唯一分解定理。
由x數鏈的性質可以發現,將n分解為其質因數相乘的形式後,數鏈中任何乙個數必定是這些質因數的某個組合,且任意相鄰的2個質因數中後面的數必定是在前面的數的質因數的組合的基礎上再乘上另外的乙個質因數。所以很容易發現,數鏈的長度就是其質因數的次數的總和,然後將質因數泛化成物品,質因數的次數為每類物品的數量,則最後的答案就是求這些物品的多重集總排列。套用公式即可!
首先要對x進行因子分解。這樣可以得到總的因子個數c,不同的因子為f1,f2,...,fn其次方數分別為e1,e2,...,en。那麼,不同序列的個數為c!/(e1!e2!......en!)。
演算法設計
陣列factorial,若factorial[i]=k則k=i!,即每個元素存放其下標的階乘值。初始化將階乘算出來打表,避免重複計算。那個常量n取22是應為22!還能夠儲存在unsigned long long型別變數中,再大就已經無法儲存了。變數fcount儲存x因子的數量,變數ecount儲存各個因子的次方數(重複次數)。
**
#include using namespace std;
typedef unsigned long long ull;
const int n = 22;
ull factorial[n+1] = ;
void init(int n)
void solve(ull x)
fcount += ecount;
denominator *= factorial[ecount];}}
if(x > 1)
fcount += 1;
cout << fcount << " " << factorial[fcount] / denominator << endl;
}int main()
演算法複雜度分析
由solve()函式中,for(ull i=2; i*i<=x; i++)可知,該處演算法複雜度為o(n),由init()函式中,for(int i=1; i<=n; i++)可知,該處演算法複雜度為o(n)。因此該演算法的時間複雜度為o(n)。
數論基礎之素數,約數
關於約數 唯一分解定理 任何數都可由素因子之積構成 int p 100 a 100 cnt void divide int n if n 1 for int i 1 i cnt i cout 方法2 離線做法,預處理出乙個質因子樹。預處理o nlogn 查詢乙個數o logn void init v...
LGP4714 數學 約數個數和
題目 眾所周知,除數個數函式 sigma 0 i 2 i 就是狄利克雷卷積裡的 1 函式 於是熟悉狄利克雷卷積的話很快就能看出我們要求的就是 i times i 即 i 我們給這個函式起乙個名字叫 f 顯然這個東西是積性函式,於是我們考慮一下指數次冪的 f 如何求 顯然 f n sum f d 對於...
directx數學基礎
向量 也叫向量,英文叫vector 向量就是包含大小 長度 和方向的乙個量。向量有2維的,也有3維甚至4維的。在dx的所有結構體中,有乙個結構體是用來表示3維向量的,它就是d3dvector,這個結構體很簡單,只有三個成員 x y z。一般來說,如果不涉及到向量運算的話,用這個結構體來定義乙個向量就...