模拟测试47

T1:

  题意:
    有交替的N个黑白段,长度给定,一个人脚长S,步长K,可以从任意一点出发,问是否有一种方案,能够从第一个块之前走到最后一个块以后,并且脚不碰到任何一个黑色段。

  题解:

    我们可以将该问题在模意义下解决。

    将每个黑色段的区间求出,左侧缩一的长度,右侧延伸脚长减一,这样将脚变成了一个点。

    如果某个黑色段的长度大于K,那么一定无解。将所有的黑色段左右端点取模,特判黑色段被劈成两段的情况。

    然后得到了一些区间,问题转化为0~K-1是否被全部覆盖,排序后单调指针扫一遍即可。

    时间复杂度$O(Nlog_2N)$。

T2:

  题意:

    求子树内数量最多的元素及其数量。

  题解:

    模板题。

    线段树合并,启发式合并,DFS序,分治均可。

    时间复杂度$O(Nlog_2N)$。
T3:

  题意:

    给定一个字符串,最小化一个0/1串,使得它们拥有相同的t集合。t为字符串的循环节。

  题解:

    求出所有循环节可以用KMP,串长减所有next即为t的取值集合。

    求出集合后考虑构造。

    从小到大枚举next的长度,不断构造长度等于next的0/1串。

    每次对于相邻的next,如果next[i-1]*2>=next[i],那么将当前串的后缀复制到后面。

    若next[i-1]*2<next[i],那么将后缀复制到最后,再在中间填0,如果不匹配,则将最后一个0改为1。

    证明:

      因为1和0是等效的可以互换,所以第一位一定为零。

      每次构造时,保证当前构造出的串是可行方案中字典序最小的。

      next的含义为总长度减去每个循环节的长度,所以每次构造出的串是循环节的一部分。

      根据next数组的含义,每次构造出的串要含有相同的前后缀。

      当next[i-1]*2>=next[i],那么原串中前后缀重叠,根据next数组的性质补全既可。

      当next[i-1]*2<next[i],先补全当前串,使得其满足next数组的性质,再考虑在中间添加数字。

      为了使字典序最小,添加的数字要尽可能为0,若破坏了next数组,则将最后一位改为1。

    时间复杂度$O(N)$。

posted @ 2019-09-20 15:06  hz_Rockstar  阅读(185)  评论(2编辑  收藏  举报