A - AND, OR and square sum
题意:给出n个数,每次挑两个数a,b,使其中任意一个变成a&b,另一个变成a|b。进行任意次这样的变换,求最终所有数平方和的最大值。
解:平方和的最大值要求大的数尽可能大。两个数经过一次操作,新形成两个数,与原来相比1的数量不变,也就是说操作完后所有的1任意排列,依次贪心分配,尽量把所有位填满。
B - Recover it!
题意:如果一个数x是素数,那它新生成第x个素数放在序列末尾;如果一个数x是合数,那它生成其最大的因子放在序列末尾,最后打乱顺序。按以上规则生成一个长为2n的序列,求这个序列的原数组。如果有多解,输出一个即可。
解:考虑特殊情况。最大的合数显然是原来就有的,同理最小的质数也是,依次删去它们对应的生成数,即可得到答案。注意预处理,用欧拉筛筛出所有的质数,同时也能筛出每个数对应的最小质因子。还有vector.size()返回的是无符号型整数,如果为零再减1会得到一个很大的整数,再然后就RE了。
C - Numerical Sequence (easy version)
题意:给出一个形如112123123412345的字符串,问其第k位是什么数字。
解:现算出每个字串如1 12 123 有几个数字,依此二分出它处在1到几的子串内,注意类如11有两个数字而不是一个数。然后预处理出一个1到大概15000多的子串,直接查询即可。
D - Glass Half Spilled
题意:有n个杯子,每个杯子的容量上限为ai,目前装了bi的水。水可以从一个杯子倒到另一个杯子,但杯子的形状比较尴尬,倒进去的水量等于漏掉的水量。也就是说,从一个杯子倒5ml水,最后只有2.5ml倒进了另一个杯子里。求k∈[1,n]使,任选k个杯子最大水量。
解:看数据范围是n3的dp。令dp[j]为选j个杯子的最大水量,按照国际惯例再加一维前i个杯子中。水会漏一半没事,反正倒多少都会漏一半,有限制的就是杯子容量,这听起来有些像背包,那再加一维容量。令dp[i][j][k]为前i个杯子中选j个的最大水量,目前j个杯子容量为k。k的范围好像有点大,总复杂度飙到了1e8。先不管。根据背包的转移方式,当新出现一个杯子的时候,我们可以不选,dp[i][j][k]=dp[i-1][j][k];也可以选,dp[i-1][j-1][k-a[i]]+b[i]/2.现在这个dp的值是往里倒的水的数量,最后还要加上原有水的量,如果超出杯子容量就按原有杯子容量算。最后,1e8能跑过。。。