Shu-How Zの小窝

Loading...

2025 11 10

  • 第20场 (为了完整把前天的一部分粘贴过来了
    • T1 秒了
    • T2 我不行了,啥性质都分析出来了,就是没有想到把第 \(i\) 个物品合并放到第 \(i+1\) 里去,那我能说啥呢
      • 见过的套路不够多加上当时的脑袋比较混沌,加上自己比较蠢没有想到可以这样子做,实际上我是想到了可以合并变成第 \(i+1\) 大的大小的但是我没有想到可以给它放到后面去处理,我是直接想用背包处理的,我太蠢了深刻反思
    • T3 根号分治求拆分数
      • 很天才的trick,之前从未见过/kx
      • 考虑加入的数 \(x <= \sqrt{N}\)
        • 那么直接背包,时间复杂度是 \(O(N \sqrt{N})\)
      • \(x > \sqrt{N}\)
        • 那么考虑它们加入的次数一定会小于等于 \(\sqrt{N}\) 故我们可以枚举次数,然后加入一个 \(\sqrt{N}\),可以任意地把前面的数都加上一个数 \(c >= 0\)
      • 甜菜!!!这样就是 \(O(N \sqrt{N})\) 的了
      • 考虑怎么反悔,这里有两种方法
        • 对于完全背包可以使用 退背包的操作
        • 或者考虑容斥,如不能选 \(a_1, a_2, …… a_k\) 这几个数,则考虑选了几个违法的数(不能重复选)若是 \(x\) 个则系数为 \((-1)^x\) 用背包每次加数改为加上这个数的相反数即可
        s[0] = 1;
        for (long long i = 1; i <= k; i++) {
          for (long long j = n; j >= a[i]; j--) {
            s[j] += (mod - s[j - a[i]]);
            s[j] %= mod;
          }
        }
      
    • T4
      • 看了提示之后有了点思路
      • 因为要左右两边都有比自己高的自己才能增高,所以可以得出最终序列的最大值等于原来序列的最大值
      • 然后考虑最大值所在的位置 \(x\) (任意一个)则 \(i<x\)\(i\) 都要是 \(1-i\) 的前缀最大值,任意一个 \(i > x\)\(i\) 都要是后缀最大值
      • 故我们可以确定每一个数所最终要变成的数
      • 考虑从小往大提升这座山,如第一小的提升到次小或它们最终需要变成的数,这一定是不劣的因为它们在这个阶段无法成为别人提高的媒介
      • 考虑我们维护一个集合表示最小的,且需要加到次小的数的集合,我们考虑 \(pl\) 为这些数最靠左的节点,\(pr\) 为这些数最靠右的节点,\(mxll\)\(pl\) 左边大于 \(pl\) 的最小的数,\(mxlr\)\(pl\) 右边大于 \(pl\) 的最小的数,\(mxrl\)\(pr\) 左边大于 \(pr\) 的最小的数,\(mxrr\)\(pr\) 右边大于 \(pr\) 的最小的数。
      • 我们肯定是更希望是 \((x+1,x,x+1)\) 这种形式的出现次数多,我们会想到可以把 \(pl\)\(pr\) 的值加1然后再让序列中间的元素加1,重复这个步骤直到它们和次小的数一样大
      • 考虑这样做一次的答案就是 \(\min(mxlr,mxrl) + mxll + mxrr\) 可以发现这样一定是最优的,因为 \(mxll\)\(mxrr\) 是一定要选的,\(\min(mxlr,mxrl)\) 是全局大于 \(pl,pr\) 的最小的值是最优的选择方案,然后计算一下其他的贡献即可
      • 然后直接上主席树求解即可。
      • 感觉很简单啊,还是不要惧怕题目,在NOIP考场上也要做到每道题都分配一些思考时间而不是碰到T4下意识觉得自己做不出来
  • 第21场补题
    • T2
      • 考场想出来了全部的关键点 \(a_{\frac{i}{j}}\) 可以数论分块 \(b_{i \mod j}\) 下标为等差数列,甚至想到了可以预处理等差数列的前缀和,但是我就是没有想到可以对 \(j\) 进行根号分治
        • 具体地对于 \(j <= \sqrt{N}\) 来说可以直接暴力计算时间复杂度为 \(O(N \sqrt{N})\)
        • 对于 \(j > \sqrt{N}\) 来说它的公差是 \(\frac{i}{j}\) 的是 \(< sqrt{N}\) 的故可以直接预处理出来
      • 为什么我没有想到根号分治
        • 见的不够多,说白了就是题目做少了
        • 没有总结过根号分治适用于哪些场景,它没有在我脑海中留下标签印象,适用于对静态序列的某些位置求和或其他操作等问题
        • 头疼,感觉自己见过的根号分治的题没几道,大部分原因还是要归咎在根号分治这个trick用少了上面
    • T3
      • 六百六十六烟斗不带烟的,是 \(n \cdot k <= 1e5\) 而并非 \(n,k <= 1e5\) 看错题加上思考时间不够直接炸了/fn
      • 那很显然考时我想到了把组员放在组长前面,故可以按照 \(w\) 从小到大排序,若 \(w\) 相同,则按照 \(p\) 组员在组长前面排序
      • 定义 \(f_{i,j,k}\) 表示到了第 \(i\) 个人有 \(j\) 组选好了的选了 \(k\) 个空闲组员的最小花费,然后转移即可
    • T4
      • 长度不同的情况:本质不同的子序列
        • \(f_{i,j}\) 表示以 \(i\) 结尾,长度为 \(j\) 的本质不同的子序列
        • 考虑 \(p_i\) 为第 \(i\) 个数之前最后一个等于 \(a_i\) 的位置若没有则为0
        • 很容易看出 \(f_{k,j+1} = \sum_{i=p_k}^{k-1} f_{i,j}\) 可以使用前缀和优化 (O(NM))
      • 考虑长度相同的情况
        • \(f_{i,j}\) 为 a 序列中 \(i\) 结尾, b序列中 \(j\) 结尾,本质相同的子序列个数
        • \(a_i = b_j\) \(f_{i,j} = \sum_{e=pa_i}^{i-1} \sum_{k=pb_j}^{j-1} f_{e,k}\)
        • \(g_{i,j}\) 表示以 a 序列中的 \(i\) 结尾,以 b 序列中的 \(j\) 结尾,在结尾之前本质相同但 \(a_i > b_j\) 的序列个数
        • \(a_i > b_j\)\(g_{i,j} = \sum_{e=pa_i}^{i-1} \sum_{k=pb_j}^{j-1} f_{e,k}\)
        • \(h_{i,j}\) 表示前者>后者的情况
          • \(h_{i,j} = g_{i,j} + \sum_{e=pa_i}^{i-1} \sum_{k=pb_j}^{j-1} h_{e,k}\)
        • 所以 \(ans = \sum_{i=1}^{n} \sum_{j=1}^{m} h_{i,j}\)
        • 可以使用2维前缀和优化至 \(O(nm)\)
        • 感觉也很简单,不过还是同样的问题,还是不要惧怕题目,在NOIP考场上也要做到每道题都分配一些思考时间而不是碰到T4下意识觉得自己做不出来,因为这两场是今天才改题的所以做这场的时候没有19场总结出来的问题
      • 因为长度不同的时候直接可以区分字典序大小,故我们可以对这类情况单纯讨论就有了第一种分讨
        • 因为得到的两个序列我们只关心长度,故两个序列相对独立,故我们可以对两个序列分别进行求长度为 \(j\) 的本质不同的子序列个数
      • 因为两个串比较字典序的时候是相同的一段+不同的字符+无所谓是什么的一段,它们的长度是相等的,故我们可以分别使用 \(f,g,h\) 三个数组来考虑这三件事情
posted @ 2025-11-10 14:49  睡神本神  阅读(10)  评论(0)    收藏  举报