小公尺ICPC預選賽 A 數論,dp

2021-10-25 06:39:14 字數 1737 閱讀 3540

題目大意:

給你乙個序列a1,

...,

an

a_1,...,a_n

a1​,..

.,an

​.讓你從裡面選出乙個子集s

ss,使得子集中任意兩個數都互為倍數.求最大子集.(n≤1

e5,a

i≤1e

7n \leq 1e5,a_i\leq1e7

n≤1e5,

ai​≤

1e7).

題目思路:

首先,本題的弱化版:

整除關係具有傳遞性,所以任意兩個數成倍數關係不妨轉化為:【對子集s

ss排序後相鄰兩個數成倍數關係。】

那麼有乙個很自然的類似lis的o(n

2)

o(n^2)

o(n2

)填表法.見弱化版。

這裡考慮刷表法,令dp(

i)

dp(i)

dp(i

)代表子集中都以i為約數的最大子集.然後用dp(

i)

dp(i)

dp(i

)更新所有i

ii的倍數的dpdp

dp值。根據自然數的倒數的級數定理,該方法的複雜度為:o(w

logw

)o(wlogw)

o(wlog

w)進一步優化:只用素數的倍數去更新.

因為乙個合數可以由多個素數組成。

例如: 從dp(

2)

dp(2)

dp(2

) 轉移到 dp(

12)

dp(12)

dp(12)

.要乘上6.而 6=2

∗3

6 = 2 * 3

6=2∗3.

那麼用前者的方法我們可以一步從dp(

2)

dp(2)

dp(2)到dp(

12)

dp(12)

dp(12)

.用後者的方法是從dp(

2)

dp(2)

dp(2)到dp(

6)

dp(6)

dp(6

)再到dp(

12)

dp(12)

dp(12)

//或者從2到4到12.

所以後者少了很多次無用的轉移.具體的,根據素數的倒數的級數定理,該方法的複雜度為:o(w

logl

ogw)

o(wloglogw)

o(wlog

logw

) ac**:

#include

using

namespace std;

const

int maxn =

1e7+5;

int dp[maxn]

, sz[maxn]

;int prime[maxn]

, cnt;

bool book[maxn]

;void

init()

}}intmain()

int ans =0;

int up =

1e7;

for(

int i =

1; i <= up ; i++

)printf

("%d\n"

, ans)

;return0;

}

小公尺OJ TCO 預選賽

其實粗糧oj比賽時間一直都很友好,就是題目太少,只有三題,而且質量都不咋地。a 講那麼多,答案就是k 2。隊友1分48秒切掉的題目 手速帝啊。太水就不貼 了。b 這道題題面錯漏百出,以下面為準 給定xoy平面上的n個整點,每對點 x1,y1 x2,y2 可以確定乙個矩形 矩形左上角點為 min x1...

2018 9青島網路預選賽 C

傳送門 problem c 題意 定義五個指令,判斷能否從輸入的n條指令中成功跳出迴圈,如果不能,輸出 no 反之,輸出 yes 題解 判斷某個數 0,255 是否重複來到某一指令,如果有,則肯定是個無限迴圈,輸出 no 反之,可以跳出迴圈,輸出 yes ac 1 include2 include3...

2019西湖論劍預選賽部分WP

點進鏈結發現提示 include get file 估計是檔案包含漏洞 嘗試包含index.php,發現一串base64編碼,解碼得到 a get file if a echo include get file if strpos flag a false include a 繼續解碼hint,得到...