2020北京ICPC网络选拔赛Round1-A
十月 25, 2020
给出一个长度为n<1e5的数组a
其中ai<1e7
求一个它的最大子集
使得其中的任意两数互为倍数因子关系
1 | //input |
设dp[i]表示当前选的所有数都是i的因子的最优解(最大值)
此题能开int 1e7大小的数组
最直观的转移就是用dp[i]更新所有i的倍数的dp值 即
1 | for(int i=1;i<=Max;i++){ |
这样极限复杂度超过1e8
实际上就只用枚举i的素数倍就可以 因为合数可以倍若干个素数乘积凑出来
没必要再枚举
比如 i=30
我只用枚举它的素数倍即更新
dp[30×2]=max(dp[30×2],dp[30])…..dp[30×5]=max(dp[30×5],dp[30])
那为什么不用更新dp[30×6]?
因为在枚举它的素数倍时已经更新了dp[30×2]和dp[30×3]
dp[30×6] 会在之后dp[60×3]和dp[90×2]被更新到
复杂度和埃氏筛相同(?个人记得这个是nlogn的复杂度) 为O(XloglogX) 其中X=1e7
1e7内的素数可以通过欧拉筛或埃氏筛处理
1 | for(int i=2;i<=Max;i++){ |
不加埃氏筛直接处理它的所有倍数 可以卡进1s但是理论复杂度超过1e8
1 |
|
查看评论