[NFLSPC #6] 等差数列

考虑枚举公差 \(d\),如何求得最少题数 \(m\)

贪心的想,我们希望的等差数列是一条直线,而增加的数最少就相当于让直线最低且任意点不低过原序列。扫一遍序列,动态维护当先最少需要增加的数 \(f\) 和当前末项大小 \(g\),如果下一项 \(a_i<g-d\),那么直接把下一项增加 \(g-d-a_i\) 即可,否则需要把直线上移 \(a_i-(g-d)\)。归纳不难得出这样是最优的。

得到结论,令 \(f(d)=m\),大胆猜想 \(f\) 是单谷函数。

为什么?考虑直线变斜的过程,我们称完全贴合原序列的点为支点,那么不难发现支点是逐渐后移的。又因为斜度的增加,支点前的点贡献一定单调不减,支点后一定单调不增。所以支点前总贡献不降,支点后总共献不增。又因为 \(f(d)\) 就是这两个贡献加起来,所以 \(f(d)\) 是单谷的。

『STA - R3』Aulvwc

首先有一个显然的结论:划分出来的子序列平均数必然是整个序列的平均数。每个划分平均数是相等的,所有划分的平均数的平均数就是全局平均数,所以结论得证。

为了去除数字数量的影响,进行一步转化:将所有数减去平均数 \(avg\)。这样平均数就为 \(0\)。整个序列和为 \(0\),只要有非全集子区间和为 \(0\),就可以把序列分成两个集合使其合法。

经典的,考虑 bitset 维护。

因为要求了不是全集,我们就钦定任意一个数不选,对剩下的数判断。这样是对的,因为至少有两个集合和为 \(0\),而不选的那一个数最多破坏一个集合。

一个 bitset 记录当前可组合出的数,称其为 \(b\);一个 bitset 记录加入一个数后新增可以被表示的数,称其为 \(c\)。强制钦定选新增的数 \(a_i\),所以 \(c\) 根据 \(b\) 左右移 \(a_i\) 位更新,当前可以表示的数为 \(b\)\(c\) 的按位或,只需要判断 \(c\) 是否包含 \(0\) 即可。复杂度 \(O(\frac{n^2\times|a|}{\omega})\)

邮箱题

先考虑第一问。

假设现在在点 \(u\),那么下一个能走到的新点只能是 \(p_u\)。因为新钥匙只有一把,所以这是显然的。

因为上述结论,走路其实就是在走置换环,能走到的点也是环上连续的。那么拉出每个置换环单独考虑。

套路的,我们可以找任意一个点断环为链,然后把这个链复制一遍。即这个链是 \(now\)\(len\),那么 \(now_i=now_{i+\frac{len}{2}}\)

视角转化到链上。问题转化为对于每个点 \(u\) 求出它能走到的最远的点 \(ans_u\)

结论:对于一个起始点 \(u\),如果能走到 \(v\),那么一定能走到 \(ans_v\)

钥匙和边是固定的,所以之前能走的现在一定能走。

这个结论启发我们倒着处理 \(ans\)

对于一个起始点 \(u\),暴力往后跳,每次跳到 \(v\) 就直接跳到 \(ans_v\)。这样复杂度是对的,因为对于一个点 \(u\),它现在可以走到 \(u+1\),那么它未来也一定可以走到,也就是说每个相邻的点只会被真正跳过一次,其他时候都会被优化掉。

那么现在问题就转化为满足什么条件下点 \(u\) 能到点 \(u+1\)

视角来到固定起始点后,定义点 \(u\) 最远向前能走到点 \(a_u\),最近能从点 \(las_u\) 走到点 \(u\)

结论:点 \(u\) 能走到点 \(u+1\) 当且仅当 \(a_u\le las_{u+1}\)

因为对于 \(v< u\)\(v\) 一定能走到 \(v+1\),所以结论是显然的。

接下来考虑快速维护这两个数组。

观察到 \(las\) 不会随着起点改变而改变,那么就先扫一遍所有边,求出 \(las\)

因为相邻点都有连边,所以一个强连通分量必然是由一个区间的所有点组成。而 \(u\)\(a_u\) 必然强连通,所以 \(a_u\) 的值就是 \(u\) 所在强连通分量的最左点。

向后的边贡献 \(las\),向前的边挂在前面的点上,类似扫描线一样不停加边。一个边 \((u,v)\) 会把两点之间所有强连通分量合并,那扫一遍每个点只会被合并一次,时间复杂度正确。

第二问不难发现就是起点所在强连通分量的大小,顺便维护即可。

Swaps

首先套路的把 \(i\)\(a_i\) 连边。注意到连出来的是内向基环树森林,每棵树之间独立,所以我们只需要研究一棵基环树,全部乘起来即可。

先看看这个树是什么东西。一个点 \(i\) 上写着他指向的点 \(a_i\),操作他可以把他和自己的出边交换,然后因为这个两个点已经改变,他们就不能操作了。

有一个结论:对于一个点,他只能交换一次。因为他交换一次后,他上面就写着自己了,再交换对序列没有影响。

所以先考虑树的情况。每个点可以选择操作或者不操作,同时每个点的儿子只能有一个点选择操作。而因为操作完一个点后他和他的父亲都不能再操作了,所以我们必须自上而下的执行所有操作,即每个操作对应的最终结果是唯一的。把他写成 DP,其中 \(v\) 为儿子,\(son\) 为儿子个数。

\[f_u=\prod f_{v}\times(son+1) \]

接下来考虑环怎么搞。先看看这个环是什么东西,每个点上写着不同的数,操作他可以把他和他下一个点交换,然后他们就不能操作了。

我们可以把环上每一个点看成一个根,儿子有连向他的树点和环上他前面的一个点。对他进行上面的转移。

不过我们发现环上会有一些奇怪的限制。比如不能所有环上的点都选择操作,因为这样必然会有一个点无法执行自己的操作。

继续对限制进行探讨,发现如果只有一个点选择不操作,最终的局面一定是每个点都写这他上一个点写的数,即他自己。这个时候那个选择不操作的点也不能和树上的点交换。

继续对限制进行探讨,发现如果有两个点以上的点选择不操作,就没有怪事了,因为环被断成两个链,就没有环的性质了。

所以对于一个环上的点:

\[f_u=\prod f_{v} \]

最终环上的答案,其中 \(son_u\) 表示点 \(u\) 树点儿子个数:

\[rans=\prod f_{u}\times(son_u+2) \\ cans=\prod f_{u}\\ dans=\sum son_u+1\\ ans=\prod (rans-cans\times dans) \]

其中 \(rans\) 表示不考虑所有环限制的操作方案数。\(cans\) 表示除环以外所有树的操作方案数。\(dans\) 表示环上只有一个点不选择操作的方案数。因为只有一个点不选择操作要保留一种情况,和所有点都选择操作抵消,所以最终答案就是上述东西。

注意自环要特判。

「JZOI-1」拜神

先跑 SA。

二分长度 \(L\),check 就看有没有 \(\text{lcp}>=L\) 的。

放到 SA 上相当于从大到小扫 height,每次合并两边的块,求 \(L\) 这个版本区间内是否存在两个数在相同块中。

先看后面的问题,我们可以维护每个版本每个位置在序列上是同一个块的后继,存在就变成区间最小值在区间内,这可能可以主席树。

然后就是如何合并两个块,容易想到启发式合并。set 维护每个块中的点,每次合并更新主席树。接着处理询问,就是在主席树上查区间最小值。

[Ynoi2004] rpmtdq

枚举一下做法,发现可以支配对。即我们只需要保留一部分点对就可以回答所有问题。对于每个没有保留的点对 \((U,V)\) 必然存在保留点对 \((u,v)\) 满足 \(U\le u,v \le V\)\(dis(u,v)\le dis(U,V)\)

再枚举一下做法,发现可以点分治。

定义 \(dis_u\) 表示 \(u\) 到分治中心的距离。对于两个点 \(u,v\),若存在一个点 \(v<w<u\) 满足 \(dis_v,dis_w\le dis_u\),那么 \(dis_v+dis_w\le dis_v+dis_u\),即 \((v,u)\)\((v,w)\) 支配。类似的,若存在一个点 \(v>w>u\) 满足 \(dis_v,dis_w\le dis_u\),那么 \(dis_v+dis_w\le dis_v+dis_u\),即 \((v,u)\)\((v,w)\) 支配。

于是查前驱后继可以简单求出。随便扫描线即可。

[湖北省选模拟 2024] 永恒 / eternity

怎么判断是否有解?

如果一个连通块黑白染色后同色块有不同的数,那么必然有解。

证明:满足条件则必然存在三个位置 \(a,b,c\) 满足 \(a\neq c\)\(ab,bc\) 相邻。那么我们可以走出:\(a/c,b,a/c,b\cdots\) 的数字。我们全选 \(a\) 后,可以把一个 \(a\) 改成 \(c\),结果会变化 \((c-a)\times 100^k\)。而 \(100^k≡1\pmod {1145141},(c-a)\neq 0\),所以可以取遍所有值。

其他情况路径是确定奇偶性的,暴力情况数 \(1145141\times 10\times 10\times 2\) 线分治维护即可。

[NOI2022] 冒泡排序

干掉矛盾是容易的。

首先答案序列可以调整为 \(a_i\in V\)

性质 A:限制形如某些区间全为 \(1\),有些区间必须有 \(0\)。那么 \(0\) 肯定贪心的往前选。

性质 B:单点赋值的限制,可以扫描线+线段树+DP。

性质 C:最小值放前面不劣,多了一点大于某一数的限制。还是可以扫描线+线段树+DP。

那么考虑把原题一堆限制改为一些 \(=v\) 一些 \(\ge v\) 的限制。

两个相交的区间若 \(V\neq V\) 则可以缩小一个区间。那么现在相交的全部 \(V=V\),包含的是单调递增的。每个区间第一个数放 \(=V\) 条件,其他位置放 \(>V\) 条件即可。

之后树状数组线段树简单维护。

posted on 2024-09-11 16:08  lizhous  阅读(6)  评论(0编辑  收藏  举报