题目简述:给定$1 \leq n \leq 10^6$个正整数$1 \leq a_i \leq 10^{12}$,修改第$i$个正整数$a_i$的花费为$1 \leq e_i \leq 10^9$,以及正整数$1 \leq k \leq 10^{12}$。要求选出若干个正整数进行一次修改,使得修改后所有正整数的最大公约数等于$1$。修改操作为:对于正整数$a$,选择$a$的一个约数$d \leq k$,把$a$修改为$a/d$。设选出并修改的正整数有$x$个,他们的花费之和为$y$,则总的修改花费为$xy$。求最小花费。

解:code

设$d = \gcd (a_1, a_2, \dots, a_n) = p_1^{s_1} p_2^{s_2} \dots p_m^{s_m}$,其中$p_i$为互不相同的质数且$s_i \geq 1$。由$d \leq 10^{12}$,可知$m \leq 11$。

观察1:若$a_i$存在不同于$p_1, p_2, \dots, p_m$的质因数$p$,则将$a_i$替换为$a_i/p$不会影响最小花费。

故可假设$a_i = p_1^{s_{i1}} p_2^{s_{i2}} \dots p_m^{s_{im}}$,我们称满足这一条件的$a_i$为“正规化”的。

观察2:正规化的$a_i$序列中,不同元素个数$M \leq 11598$。这个上界当$d = 2 \cdot 3 \cdot 5 \cdot 7 \cdot 11 \cdot 13$时取到。

我们修改$a_i$的目标是,对任意$1 \leq j \leq m$,都存在一个$a_i$,使得$p_j \not| a_i$。为了最小花费,显然对任一$d$的质因数$p_j$,我们只需要选择恰好一个$a_i$,将其修改为不被$p_j$整除即可。因此:

观察3:我们最多只需要修改$m$个$a_i$。

从而真正有用的(即可能被修改的)$a_i$只能是:每种正规化$a_i$中,$e_i$值最小的$m$个。总共$m M$个。

对$mM$个真正有用的每个元素$(a_i, e_i)$, 枚举从$a_i$中除去的质因数的所有可能组合(一共需要检验$2^m-1$种可能)。若$a_i$可以除去质因数组合$s$,则记为$s \models a_i$。

我们把$(a_i, e_i)$按照$e_i$从小到大排序。令$F[i][x][s]$表示前$i$个元素中修改$x$个元素,且$s$描述了所除去的质因数的情况下的最小花费。则

$$ F[i][x][s] = \min_{t \subseteq s, t \models a_i} \{ F[i-1][x][s], F[i-1][x-1][s-t]+e_i \}. $$

动态规划有用状态数为$mM2^m$。

真正有用的元素及其除去的质因数组合并非$mM2^m$种,而是$m 2^m$种,因为对于每一种除去的质因数组合,我们同样也只会关心$e_i$值最小的$m$个。故在动态规划状态转移时,只需要考虑有用的元素及其质因数组合,假设$s$是【有用的$(a_i, e_i)$】的有用质因数组合,我们只需考虑以下动态规划转移:

$$ F[i+1][x+1][s \cup t] \gets \min \{ F[i+1][x+1][s \cup t], F[i][x][t]+e_i \}, $$

其中$t \cap s = \emptyset$。即,$t$枚举$s$的补的子集。(枚举子集方式可参见这里。)此种转移数至多为$m^2 3^m$。

综上,时间复杂度为$O(n \log n+m M 2^m+m^2 3^m)$。

CodeForces 1103D. Professional layer的更多相关文章

  1. Professional layer CodeForces - 1103D (状压,gcd)

    大意: 给定$n$元素序列$a$, 现在想要让$gcd(a_1,a_2,...,a_n)=1$. 对于每个$a_i$可以除以一个不超过$k$的因子, 代价为$e_i$, 假设一共选择了$x$个元素去除 ...

  2. CF1103D Codeforces Round #534 (Div. 1) Professional layer 状压 DP

    题目传送门 https://codeforces.com/contest/1103/problem/D 题解 失去信仰的低水平选手的看题解的心路历程. 一开始看题目以为是选出一些数,每个数可以除掉一个 ...

  3. 【题解】CF1103D Professional layer

    [题解]CF1103DProfessional layer 神题做前先\(orzyyb\) 一个很好的性质(之前也见过但是没有想到的) zhengchu \(gcd\le 10^{12}\) 所以不同 ...

  4. CF1103D Professional layer 状压DP

    传送门 首先对于所有数求gcd并求出这个gcd含有的质因子,那么在所有数中,只有这一些质因子会对答案产生影响,而且对于所有的数,每一个质因子只会在一个数中被删去. 质因子数量不会超过\(11\),所以 ...

  5. CF1103D Professional layer dp

    正解:dp 解题报告: 传送门! 首先不难想到求个gcd,然后把gcd质因数分解成p1w1*p2w2*p3w3*...*pmwm 显然只要满足对每个p有一个ai%pj!=0就好,也就是说对每个pj找出 ...

  6. CodeForces 589B Layer Cake (暴力)

    题意:给定 n 个矩形是a*b的,问你把每一块都分成一样的,然后全放一块,高度都是1,体积最大是多少. 析:这个题,当时并没有完全读懂题意,而且也不怎么会做,没想到就是一个暴力,先排序,先从大的开始选 ...

  7. Codeforces Round #102 (Div. 1) A. Help Farmer 暴力分解

    A. Help Farmer 题目连接: http://www.codeforces.com/contest/142/problem/A Description Once upon a time in ...

  8. April Fools Day Contest 2016 G. You're a Professional

    G. You're a Professional 题目连接: http://www.codeforces.com/contest/656/problem/G Description A simple ...

  9. CodeForces 35D Animals

    G - Animals Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit  ...

随机推荐

  1. Mysql学习记录点

    order by 数字,表示按照第几列来排序,可以从1开始,不能是0,也不能超过列数.

  2. vim修改二进制文件

    先用vim以二进制格式打开需要编辑或查看的文件,不采用-b参数有时会导致转换错误,详见分隔线后部分.    vim -b file-to-open.dat 然后用xxd把文件转换成十六进制格式 :%! ...

  3. 转:CEO, CFO, CIO, CTO, CSO是什么

    转自:https://club.1688.com/threadview/26957122.html CEO, CFO, CIO, CTO, CSO是什么?(现在O太多了) 帖子创建时间:  2009年 ...

  4. 【Android小项目】找不同,改编自"寻找房祖名"的一款开源小应用。

    近期在微信朋友圈"寻找房祖名"和"万里寻刀"这类小游戏比較火.我试着写了一个android版本号的,里面全是一系列的形近字,实现原理非常easy:用一个Grid ...

  5. 消息列队 php 基于redis 实现

    说明 消息列队 基于PHP 实现. 之前 用python 的 flower 实现了 列队. 今天这里我们用的是 PHP 来实现: 在实际的业务环境中 PHP 用的多些: PHP 实现列队 最重要的是用 ...

  6. easyui datagrid client搜索、分页、排序

    easyui datagrid的排序默认是server端排序.能够用sorter实现client排序[2].client分页可用filter实现[3].client搜索相同能够用filter实现. 不 ...

  7. HDU-1076-An Easy Task(Debian下水题測试.....)

    An Easy Task Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tot ...

  8. unix && linux

    区别和联系 Linux和UNIX的最大的区别是,前者是开发源代码的自由软件,而后者是对源代码实行知识产权保护的传统商业软件.这应该是他们最大的不同,这种不同体现在用户对前者有很高的自主权,而对后者却只 ...

  9. ArcGIS教程:分水岭

    摘要 确定栅格中一组像元之上的汇流区域. 使用方法 · 各个分水岭的值将取自输入栅格中源的值或者要素倾泻点数据.假设倾泻点为栅格数据集,则使用像元值.假设倾泻点为点要素数据集,则从指定的字段中获取值. ...

  10. C语言socket send()数据缓存问题

    send()函数默认情况下会使用Nagle算法.Nagle算法通过将未确认的数据存入缓冲区直到积攒到一定数量一起发送的方法.来降低主机发送零碎小数据包的数目.所以假设send()函数发送数据过快的话, ...