【題目背景】
陰天傍晚車窗外
未來有乙個人在等待
向左向右向前看
愛要拐幾個彎才來
我遇見誰會有怎樣的對白
我等的人他在多遠的未來
我聽見風來自地鐵和人海
我排著隊拿著愛的號碼牌
【題目描述】
城市中人們總是拿著號碼牌,不停尋找,不斷匹配,可是誰也不知道自己等的那個人是誰。
可是燕姿不一樣,燕姿知道自己等的人是誰,因為燕姿數學學得好!燕姿發現了乙個神奇的演算法:假設自己的號碼牌上寫著數字 s,那麼自己等的人手上的號碼牌數字的所有正約數之和必定等於 s。
所以燕姿總是拿著號碼牌在地鐵和人海找數字(喂!這樣真的靠譜嗎)可是她忙著唱《綠光》,想拜託你寫乙個程式能夠快速地找到所有自己等的人。
輸入格式:
輸入包含k
組資料。對於每組資料,輸入包含乙個號碼牌s。
輸出格式:
對於每組資料,輸出有兩行,第一行包含乙個整數m,表示有m個等的人。
第二行包含相應的m
個數,表示所有等的人的號碼牌。
注意:你輸出的號碼牌必須按照公升序排列。
【input】
42
【output】
3
2026
41
【分析】
首先這題要用到幾個數論裡的定理,當我第一眼看這些定理的時候,我是很懵逼的。先給出定理的公式。
首先,這裡要用到
1.惟一分解定理:
2.約數和定理 :
首先惟一分解定理:每個大於1的自然數n均可分解為有限個素數之積,就比如
【input】
12
【output】
223
1
下面是**實現
通俗一點就是一下:約數和定理:
比如 20 = 22 +51 (惟一分解定理)
20的所有正約數的和為
(20 +21 +22) *(50+ 51)=42
而這裡的42就是題目中號碼牌s,20是自己等的人手上的號碼牌數字,那這樣子這題就懂啦。
那麼我們可以通過列舉ai和pi來求出m從而得到n,具體的話只要乙個括號內的總和能被m整除那麼ai,pi合法,然而這樣需要算出2*109以內的質數。但是注意到p>=2,那麼就只需要求出根號範圍內的質數即可,注意處理m-1的特殊情況。
這裡先介紹一下線性篩質數(其實相當於我自己在學習)
線性篩:o(n)
1.線性篩的思想就是用最小的質因子把他篩掉
2.從小到大列舉,所以當前的大於,以後的一定大於
3.其實就是埃氏篩的公升級版
int pr[n],v[n]
;//v[i]是i的最小質因子 ,pr[n]是用來存質數的陣列
void
prime()
for(
int j=
1;j<=m;j++
)//列舉所有質數
v[i*pr[j]
]=pr[j]
;//i%pr[j]=0 ->pr[j]是i的最小質因子 ,pr[j]就是咱們的i*pr[j]最小質因子也一定是 pr[j]
}//!=0-> pr[j]不是i的最小質因子, 從小到大列舉,i的最小質因子一定是大於 pr[j]
// pr[j]的最小質因子是pr[j]
//i*pr[j]的最小質因子就是pr[j]
//i * prime[ j ]也就是質數prime[ j ]作為最小質因子能夠篩掉的部分合數
}}
下面上這題的**:
#include
using
namespace std;
#define n 1000100
int pr[n]
,ans[n]
, v[n]
;//v[i]是i的最小質因子 ,pr[n]是用來存質數的陣列
int cnt,m;
void
prime()
for(
int j=
1;j<=m;j++
)//列舉所有質數
v[i*pr[j]
]=pr[j]
;//i%pr[j]=0 ->pr[j]是i的最小質因子 ,pr[j]就是咱們的i*pr[j]最小質因子也一定是 pr[j]
}//!=0-> pr[j]不是i的最小質因子, 從小到大列舉,i的最小質因子一定是大於 pr[j]
// pr[j]的最小質因子是pr[j]
//i*pr[j]的最小質因子就是pr[j]
//i * prime[ j ]也就是質數prime[ j ]作為最小質因子能夠篩掉的部分合數}}
bool
check
(int x)
//判斷是否是素數
for(
int i =
2; i*i <= x; i++
)return1;
}//上乙個質數的下標,拼湊出來的結果,nowleft剩下的成分
void
dfs(
int nowleft,
int product,
int sum1)
//nowleft是拆分後剩餘的部分,product是前面的質數的積
//sum1就是約數和(形如pow(p1,a1)*pow(p2,a2)*...這樣的式子)
//保證now-1至少是2if(
check
(nowleft-1)
&&nowleft-
1>pr[product]
) ans[
++cnt]
= sum1*
(nowleft-1)
;//這是只含乙個的大於sqrt(num)的質數
//降低時間複雜度,防爆int
for(
int i = product+
1; pr[i]
*pr[i]
<=nowleft; i++)}
return;}
intmain()
return0;
}
2017 9 11 聰明的燕姿 失敗總結
這題有毒 如假包換的爆搜 只要知道乙個數的約數加起來 分解質因數後每個 質因數1 pi次字首和 相乘的結果 就好 做 sou 了 所以如果知道約數和,就可以列舉質因數來爆搜 必須剪枝到極致才能過,不然會t 由於約數和 一堆數的乘積,所以有乙個剪枝是只有能整除才去搜 由於分解的質因數不能重,所以遞迴剩...
acWing 1296 聰明的燕姿
用到了算數基本定理的思想,尤拉篩的不記錄最小質因子的板子,另外在優化dfs的時候還用到了小學生求素數的一點小思想,下面我們簡單說一下思路和分析幾個問題。思路 正約數之和等於s的數,容易想到直接列舉每乙個質數與每乙個質數的數量,然後進行優化。第乙個問題 尤拉篩存質數的陣列到底開多大?這個問題,誰一開始...
聰明的燕姿 JLOI2014
陰天傍晚車窗外 未來有乙個人在等待 向左向右向前看 愛要拐幾個彎才來 我遇見誰會有怎樣的對白 我等的人他在多遠的未來 我聽見風來自地鐵和人海 我排著隊拿著愛的號碼牌 城市中人們總是拿著號碼牌,不停尋找,不斷匹配,可是誰也不知道自己等的那個人是誰。可是燕姿不一樣,燕姿知道自己等的人是誰,因為燕姿數學學...