zoukankan      html  css  js  c++  java
  • Codeforces Round #670 题意及思路

    A题

    题意

    题目给出 $ t $ 组数据,对于每组数据:
    给出一个数列,你需要将这个数列划分成两个集合 $ A $ 和 $ B $ ,并最大化 $ mex(A)+mex(B) $ 。
    $ mex $ 的定义:$ mex(A) $ 为最小的没有在集合 $ A $ 中出现过的非负整数的值。

    思路

    如果整个数列没有 $ 0 $ ,那么答案肯定是 $ 0 $ 。
    如果有 $ 1 $ 个 $ 0 $ ,那么其中一个集合的 $ mex $ 值肯定是 $ 0 $ 了,不妨另该集合 $ A=∅ $ ,使所有数都在另一个集合 $ B $ 中,答案即为 $ mex(B) $ 。
    如果有 $ 2 $ 个 $ 0 $ ,那么 $ 2 $ 个 $ 0 $ 一定要分成 $ 2 $ 组放,那么再用同样的方法研究 $ 1 $ 。
    总结以上步骤,先统计每个数出现的次数, $ mex $ 较小的集合的 $ mex $ 值应该是从 $ 0 $ 开始第一个不足 $ 2 $ 个的数 $ x $ ,$ mex $ 较大的集合的 $ mex $ 值应该是从 $ 0 $ 开始第一个没有的数 $ y $ 。答案即为 $ x+y $ 。

    B题

    题意

    题目给出 $ t $ 组数据,对于每组数据:
    给定 $ n $ 个数,找出 $ 5 $ 个数,让它们的乘积最大。每个数可正可负。

    思路

    如果只有 $ 5 $ 个数,输出这 $ 5 $ 个数的乘积。
    如果最终得到的乘积一定是负数(即所有的数都是负数),则选择最大的 $ 5 $ 个负数。
    如果最终得到的乘积一定是 $ 0 $ (即不足 $ 5 $ 个非零数),则答案为 $ 0 $ 。
    否则分类, $ 5 $ 个数中选择 $ 0,2,4 $ 个负数。

    C题

    题意

    题目给出 $ t $ 组数据,对于每组数据:
    给出一棵树,你需要通过,先任意删除一条边,再任意增加一条边,使得树的重心个数只有一个,且仍满足为树的形式。

    思路

    有一个结论,就是树的重心只有可能是 $ 1 $ 个或 $ 2 $ 个,且如果有 $ 2 $ 个,这两点一定相邻。
    如果有 $ 1 $ 个重心,随意删去一条边,再把他加回来。
    如果有 $ 2 $ 个重心,设两个重心为 $ c_1,c_2 $ ,可以删去 $ c_2 $ 和非 $ c_1 $ 的点 $ v $ 的边,然后把 $ v $ 和 $ c_1 $ 连起来。易证明这是正确的。

    D题

    题意

    给定一个序列 $ a_1,a_2,...a_n $ ,长度为 $ n $ 的序列 $ b,c $ ,满足 $ a_i=b_i+c_i $ ,且 $ b $ 为不下降序列, $ c $ 为不上升序列。
    有 $ q $ 个操作,每次操作可以把 $ [l,r] $ 的数增加 $ x $ 。求每次操作后最小的 $ max(b_i,c_i) $ 。

    思路

    先考虑原始序列,设 $ k $ 为正数,若 $ a_{i+1}=a_i+k $ ,那么 $ b_{i+1}=b_i+k,c_{i+1}=c_i $ ;若 $ a_{i+1}=a_i-k $ ,那么 $ b_{i+1}=b_i,c_{i+1}=c_i-k $ 。$ max(b_i,c_i) $ 一定是 $ b_n,c_1 $ 中的一个。为了使答案最小,应该使 $ b_n,c_1 $ 尽量接近,即相差 $ 0 $ 或 $ 1 $ 。那么我们可以假设 $ a_0=0,b_0=0 $ ,然后根据上述规则分别求出 $ b_n,c_1 $ ,最后的答案为 $ ceil(b_n+c_1)/2 $ 。
    然后再考虑如何更新答案,如果暴力更新时间复杂度是 $ O(nq) $ 。思考求出 $ b_n,c_1 $ 的过程。设 $ {d_n} $ 为 $ {a_n} $ 的差分数列,则 $ b_n $ 是 $ {d_n} $ 正项之和, $ c_1 $ 不是 $ d_1 $ 就是 $ 0 $ 。而区间加可单点修改 $ {d_n} $ ,时间复杂度变为 $ O(n+q) $ 。

    E题

    题意

    交互题。
    已知 $ n $ , 有一个未知数 $ x (1≤x≤n) $ ,你需要求出 $ x $ 的值。
    一开始,你有一个集合 $ S $ 由从 $ 1 $ 到 $ n $ ,你可以对这个集合执行不超过 $ 10000 $ 次 $ A,B,C $ 操作(总和不超过)。
    $ A: A a $ ,表示求出 $ S $ 中 $ a $ 的倍数的个数 $ (1≤a≤n) $ .
    $ B: B a $ ,表示求出 $ S $ 中 $ a $ 的倍数的个数并将这些 $ a $ 的倍数从 $ S $ 中删去( $ x $ 是不会被删掉) $ (2≤a≤n) $ 。
    $ C: C a $ ,表示你知道了 $ x=a (1≤a≤n) $ 。
    $ a $ 为整数。

    思路

    很容易想到一个暴力做法:对于每一个小于 $ n $ 的质数 $ p_i^1 $ ,删除 $ p_i^1 $ 的倍数后询问 $ p_i^1 $ 的倍数剩余多少个,如果有剩余说明 $ p_i $ 是 $ x $ 的质因子,再依次删除并询问 $ p_i2,p_i3...p_i^k $ 是否有剩余,找出 $ p_i $ 的个数,并计入答案。但是 $ 1e5 $ 以内的质数有 $ 9562 $ 个,每一个都这样操作会超过限制,需要优化。
    容易想到的是: $ x $ 里至多含有 $ 1 $ 个大于 $ sqrt(n) $ 的质因子。故对于不大于 $ sqrt(n) $ 的数,我们可以采用暴力做法,即最多只有 $ 66 $ 个质数采用暴力做法,可以接受。此时分两种情况。

    1. $ x $ 有不大于 $ sqrt(n) $ 的质因子,那么就依次删除并查询当前答案与大于 $ sqrt(n) $ 的质数的乘积是否有剩余,如果有剩余那么就是这个数,如果全部无剩余那就是当前答案。
    2. $ x $ 无不大于 $ sqrt(n) $ 的质因子,那么答案只有可能是大于 $ sqrt(n) $ 的某一质数或者 $ 1 $ 。大于 $ sqrt(n) $ 的质数仍有很多,不能暴力处理。可以用分块的思想,先统计一次剩余数的个数,然后删除 $ 50 $ 个数,再次统计剩余数的个数,如果正好少 $ 50 $ 个则可以继续向后查询,如果只少了 $ 49 $ 个那说明 $ x $ 在这 $ 50 $ 个数之中。如果也没有大于 $ sqrt(n) $ 的质数,那么答案就是 $ 1 $ 了。

    特殊的,感觉 $ n=1 $ 的时候要特判。

    提交记录

    写的很乱,请多多包容!!!
    $ A $ 题: A
    $ B $ 题: B
    $ C $ 题: C
    $ D $ 题: D
    $ E $ 题: E

  • 相关阅读:
    A1052. Linked List Sorting (25)
    A1032. Sharing (25)
    A1022. Digital Library (30)
    A1071. Speech Patterns (25)
    A1054. The Dominant Color (20)
    A1060. Are They Equal (25)
    A1063. Set Similarity (25)
    电子码表
    矩阵键盘
    对象追踪、临时对象追踪、绝对坐标与相对坐标
  • 原文地址:https://www.cnblogs.com/Mercury04/p/13701205.html
Copyright © 2011-2022 走看看