codeforces div.3 1005
C. Summarize to the Power of Two
- 如果对于数组中的任意元素,在数组中都能够找到一个其他的元素,这两个数字的和是2的幂次。那么这个数组被认为是合法的。现在,问,你至少要从这个数组中剔除多少元素,使得这个数组合法。
- map。
- 先把所有的元素扔到map里,然后对于每个元素,枚举2的幂次,寻找差值,看是否能够找到。注意,如果一个元素找到的是他本身,例如8+8=16。这个时候要判断8是否出现过大于1次。
D. Polycarp and Div 3
- 给定一个数列,将他分割为一段一段的。问如何分割,能使他被3整除的段数最多。
- 3|1|21 2|0|1|9|201|81
- dp[i][j]代表到i这一位为止,最后的连续位模3余j的最大段数是多少。
考虑第i位,如果这一位能够被3整除,那么dp[i][0]=max(dp[i-1][0],dp[i-1][1],dp[i-1][2])+1
dp[i][1]=0
dp[i][2]=0
如果这一为模3余1,那么dp[i][0]=max(dp[i-1][0],dp[i-1][2]+1)
dp[i][1]=max(dp[i-1][0],dp[i-1][1],dp[i-1][2])
dp[i][2]=dp[i-1][1]
如果这一位模3余2,dp[i][0]=max(dp[i-1][0],dp[i-1][1]+1)
dp[i][1]=dp[i-1][2]
dp[i][2]=max(dp[i-1][0],dp[i-1][1],dp[i-1][2])
E1. Median on Segments (Permutations Edition)
- 给定一个数组,数组是一个排列,给你一个数k,问在多少的区间里,这个k是中位数。(如果是偶数长度,那么k为第n/2个)
- 给数组中的数打上标记,如果这个数>k,记为1,<k记为-1,k为0,计算前缀和。我们将k这个位置之前的数都加入到计数数组中,然后对于大于等于k的位置进行询问。可以发现,在前缀和数组中,若sum[j]-sum[i]==0||sum[j]-sum[i]=1,则i,j的区间是合法的。O(n)查询即可。
E2. Median on Segments (General Case Edition)
- 给定一个数组,给你一个数k,问在多少的区间里,这个k是中位数。(如果是偶数长度,那么k为第n/2个)
- 我们对<=k的标记为-1,大于k的标记为1。此时如果一个区间的和<=0,那么这个区间的中位数一定小于等于k。
- 下一步,我们对<=k-1的标记为-1,大于k-1的标记为1。如果一个区间的和<=0,那么这个区间的中位数一定小于等于k-1。
- 两者做差,就是中位数为k的。上述过程可通过树状数组解决。
F. Berland and the Shortest Paths
- 有n个点,m条路径,你需要删减为n-1条边,并且使得从1这个点到其他的距离和最短。输出所有方案。
- 可以发现,每个点到1这个点的最短距离一定不变。所以只需计算这个点有几种方案使得距离和最短即可。然后每个点的方案相乘,就是所有的方案。bfs()即可。