AcWing1296 聰明的燕姿

2022-05-29 19:12:16 字數 1525 閱讀 4796

解題思路:

首先我們肯定要用到約數之和定理

但是有個問題就是要怎麼用

根據經驗得知,約數最多也就六七個左右,不然直接就超了s的範圍。所以我們考慮用爆搜來做

但是用爆搜的話還是要優化一下思路和用什麼順序去搜尋。

順序:

按照p和α的順序來列舉

一旦s%這個當前的乘積==0(dfs的精髓)

那才能跳到下一層迴圈因為這樣才符合約數和定理

可能要想一些剪枝:

當s等於1+p的時候,直接就得到乙個答案。這樣就可以少遍歷幾個

小於s的質數的個數有s除以logn個

時間複雜度:\(o(10\sqrt*100)\)

十個約數,然後再判斷質數的個數。k組資料

#include #include #include using namespace std;

const int n = 50000;

int primes[n], cnt;

bool st[n];

int ans[n], len;

void get_primes(int n)

}}bool is_prime(int x)

void dfs(int last, int prod, int s)

if (s - 1 > (last < 0 ? 1 : primes[last]) && is_prime(s - 1))

ans[len ++ ] = prod * (s - 1); // 不可以寫primes[last]因為可能是第乙個

for (int i = last + 1; primes[i] <= s / primes[i]; i ++ )

}int main()

}return 0;

}

解題技巧創造出來

演算法創造出來比較少

#include#include #include #include using namespace std;

const int maxn = 50000 + 10;

int ans[maxn], len, cnt;

int primes[maxn];

bool st[maxn];

void get_primes(int n)

}}bool is_prime(int n)

return true;

}void dfs(int last, int prod, int s)

if(is_prime(s - 1) && s - 1 > (last < 0 ? 1 : primes[last])) ans[len++] = prod * (s - 1); // primes[last + 1]的話可能會出錯

for(int i = last + 1; primes[i] <= s / primes[i]; i++)

} }int main()

}return 0;

}

acWing 1296 聰明的燕姿

用到了算數基本定理的思想,尤拉篩的不記錄最小質因子的板子,另外在優化dfs的時候還用到了小學生求素數的一點小思想,下面我們簡單說一下思路和分析幾個問題。思路 正約數之和等於s的數,容易想到直接列舉每乙個質數與每乙個質數的數量,然後進行優化。第乙個問題 尤拉篩存質數的陣列到底開多大?這個問題,誰一開始...

AcWing 1296 聰明的燕姿

原題鏈結 考察 dfs 約數 錯誤思路 倍數法求出所有約數,n要開到1e9必然mle且tle 正確思路 觀察約數之和的式子 s 1 p1 p1 2 p1 3 1 p2 p2 2 p2 3 要滿足能夠這種性質的數在1 2e9內較少.再繼續觀察,假設p全為2,1 2 1 2 22 1 2 22 23 當...

AcWing 1296 聰明的燕姿

算術基本定理 任何乙個大於1的自然數 n,如果n不為質數,那麼n可以唯一分解成有限個質數的乘積 則可以對s進行分解質因數 s p1 p2 pn 根據約數之和 sum 1 p1 1 p1 2 p1 1 pn 1 pn 而任何約數之和為s的數一定可以表示為約束之和公式的形式,即 s sum 因此除了1 ...