可爱的妹子 III
noip20d5
A
呃?
B
朴素 dp 显然直接记录前面三个数,状态数 ,但是发现我们把三个数换成三个 后缀,三者之间就一定是 的关系,状态数减小为 。
C
不妨设点对 总是 的,那么对于一组询问 ,答案是 。
加入一组 时考虑实时维护所有 的答案,固定 ,一行 的变化量是 的形式,是一个绝对值函数和直线取 的结果,所以就可以变成区间加一次函数,区间加常数,两次差分即可 改一行 。
询问的时候就对 的对应行前缀和即可,时间复杂度 。
D
??
防 止 忘 记
ll exgcd( ll a , ll b , ll & x , ll & y ){
if( ! b ){
x = 1 , y = 0;
return a;
}
ll d = exgcd( b , a % b , x , y );
ll s = x - ( a / b ) * y;
x = y , y = s;
return d;
}
有解的条件是,,然后通解的形式是
CF710D Two Arithmetic Progressions 限制范围
无向图三元环级数
定向成度数小的往度数大的连边做,讨论一个点的度数是否大于根号就可以证明时间复杂度是 。
P8250 交友问题
设 是 的邻居集合,那么答案就是 ,首先我们自然想到一个显然的暴力是标记 的所有邻居再枚举 的邻居数没出现过的,时间复杂度 。
注意到我们可以离线询问,固定标记一个 然后枚举所有询问的的 算,这样时间复杂度是 。
其实等价于 ,所以我们只需要算 ,注意这样的话一次询问中 就等价了,类似无向图三元环级数的技巧,然后我们令 是 较大的那个,就在上面的暴力中让 固定。
这样的情况下我们设出一个阈值 ,若 那么上面的暴力中询问一次复杂度 ,这部分复杂度 ,若 那么由于 ,这样的 的数量为 ,固定一轮 复杂度 ,这部分复杂度 ,所以总复杂度 ,取 就能分析出 的上界。
P9744 「KDOI-06-S」消除序列
被降智之直接写了个带 的。。
P9745 「KDOI-06-S」树上异或
有显然的 dp 是令 表示子树总答案, 表示去掉 所在连通块并且这个连通块权值是 的答案,合并子树时考虑这个边连不连,,统计答案的时候就有 ,很难过。
然后因为是异或,所以套路拆位,不妨在统计答案的时候把这几位的贡献独立统计,所以可以设 表示 所在连通块的权值的第 位是 时的答案,答案变成 ,时空变成 。
[ROI 2018] Quick sort
我们考虑用冒泡排序的样子,一个一个地把 安到对应的地方,直接 swap
是 的次数,但是我们发现这个操作把所有的偶数位拉到前面,把所有的奇数位扔到后面,那么如果让要左移的数在最后的偶数位那么位置减半,所以可以做到 的操作次数了。
我们考虑倒着做这个事情,把 排好的排列用这个操作的逆来逆转回去,此时按照原排列中从后往前的顺序枚举,注意到当 位于 之间时,我们可以调整区间长度使得只需操作一步就可以将 移动到对应位置,优化之后很快啊!最后在开始之前随机 shuffle 一下防卡就稳过 的操作数了。
noip20dd12c
首先 qry1
出任意两个数 ,然后对每个位置 用 qry2
查 找匹配的,操作数 。
注意到每个数要查两遍根本是因为我们不知道差值的正负,即哪个数更大,考虑找到最小值或者最大值,然后用最值查所有的数,每个数就只需查一次。
考虑先 qry2
全集得到极差,然后二分出一个最短的前缀使得这个前缀的 qry2
存在极差,那么这个边界要么是最大值要么是最小值,随便 qry1
一个数与他比较即可,然后对所有其他数 qry2
即可。操作数 。
设求出来最值是 ,考虑一次多弄一点数,二进制分组 里面存所有第 位为 的位置,然后 qry2
然后 得到 与 每个数的差值,一个差值所有出现的 就直接定位了这个差值对应的位置。容易发现所有差值都是不同的,所以正确性可以保证。操作数 。
noip20dd16b
首先把恰好转化成小于等于,算 表示最长 段不超过 的答案,然后做个差分就能得到答案。
然后来一步转化,我们先扔进去 个 ,然后向 个空隙里面每个都塞 个 ,满足所有 的数量和是 ,那么问题转化成有 个变量 ,你需要给它们赋 的值,,问方案数。假设没有 的限制,那么用插板法易算,是 ,然而有 的限制我们就容斥,令 表示钦定了 个数 的方案数,我们把每个 的数减去 , 减去 就可以转化成原来的没有限制的问题,所以 ,,但是这样还是 的,不过我们发现对于一个 最多钦定 个 的,后面的都是 ,所以复杂度变成调和级数 。
P4859 已经没有什么好害怕的了
好像是容斥典题。 数对比 数对多 个其实就是 数对恰好有 个,先把恰好容斥成钦定 个,答案是 ,这里 是钦定 个的方案数,算这个考虑把 序列都排序,然后每个 能钦定的 就是一段前缀,设它是 ,dp 一个 表示考虑到 ,已经钦定了 个数对的方案数,那么转移的时候考虑选不选 就有 ,最后 ,时间复杂度 。
ARC096E Everything on It
第一个条件不用看,第二个条件容斥掉,令 表示钦定了 个元素出现次数 的方案数,答案是 ,然后考虑算 ,首先选出 个数是 ,其他位置的集合任意选是 ,然后枚举这 个元素有几个出现次数是 ,这些出现次数是 的则需要新建一个集合或者并入其他 个集合中,需要枚举它们分到几个集合里面,用第二类斯特林数来算它,组合起来就是
爆算就炸了,考虑优化,我们或许不需要枚举有几个元素出现了,那些没出现的元素就直接扔到一个特定的可区分的并且可空的集合 ,所以后面那部分可以枚举组数 ,变成算 个数分成 组,其中有一组是可区分的可空的方案。如果 空那么是 ,否则是 。
所以优化成
总答案是
容易做到 计算。
递推第二类斯特林数:
Gym104090M Please Save Pigeland
首先选了 后答案显然就是 ,用换根 dp 容易求出来所有的分子,对于分母 dp 的时候我们需要维护一个集合整体加 后的 ,因为更相减损术我们知道 ,整体加 后也就只需要算 ,所以我们把一个集合简化成两个数 就可以了,合并两个集合的时候 。注意这个不可减所以可能还需要处理前后缀子树答案。
时间复杂度 。
CF559C Gerald and Giant Chess
因为黑点比较少,考虑往黑点上想,不妨用全部方案减去经过至少一次黑点的的答案,先把点排序,设 表示到第 个黑点而没有经过其他黑点的方案数,有转移 ,为什么?后面的减法在算到 至少经过一个黑点的方案数,我们钦定每个 是第一个经过的黑点,剩下的随便走,容易发现这样算没有重复。
时间复杂度 。
[CQOI2011] 放棋子
考虑逐个颜色地放入全部的某一种棋子,这样会导致某些整行整列不能放棋子了,并且每个整行整列都是等价的,所以设 表示已经放入了 种颜色的棋子,目前已经占了 行 列的方案数,转移是枚举放入 个棋子要占几行几列,,其中 表示同种颜色的 个棋子占满一个 行 列的子矩形的方案数。
接下来考虑算 ,注意至多占 行 列是容易算的,就是 ,所以考虑二项式反演一下,就有 ,所以就可以愉悦爆算了,时间复杂度 。
「KDOI-06-S」合并序列
不难想到整个操作长一个三叉树的形状,而且压缩数后异或和不变,用 表示 能否被压缩成一个数,那么枚举三个区间 使得它们异或和为 且 就能更新 ,这样需要枚举共四个端点是 的,在设一个 表示 里面有没有异或和为 且可被压缩的的区间,就可以 了,但是!这个东西空间 ,如果再记录一下转移的话就爆了!
这个时候考虑把 换一个形式维护:令 是满足左端点在 里面的异或和为 且可被压缩的区间的最小的 ,就可以把空间做到 ,可以通过大概 75 分。
接下来我们再搞一个 表示两个可压缩的区间一个是 ,一个是 且异或和是 的最小的 ,于是 的转移就只需要枚举 了。
时间复杂度 。
noip20dd18b
一个重要的观察是令 表示根节点编号为 ,叶子数量为 的线段树编号和,那么固定 这是一个关于 的一次函数即 ,于是我们模拟线段树区间查询,每遇到一个完全被 包含的节点 就查询 ,这样的话只会询问 次,下面再考虑怎么求 ,因为 ,展开就有 ,,最多递归 次,可以直接记忆化,总时间复杂度 。
[省选联考 2023] 填数游戏
首先考虑一个转化,把 建点,然后对于一个 ,就在 之间连边,那么限制就是把边定向使得每个点只会被指一次,那么显然对于每个连通块必须有 ,也就是 或 ,也就是基环树或者树,现在我们对每个连通块分开讨论。
假如 Alice 的选择序列已经确定,问题就可以抽象成一条边 定向那么有 的贡献,否则有 的贡献,其中 取决于 。
看 Alice 的行为,如果 那么这一组一定没有贡献,如果 那么 Alice 选那个和 匹配的一定不劣,如果 那么 Alice 对这条边可以做的是把一条边贡献 翻转成 。
-
当前连通块是基环树。对于环我们有两种定向方案,然而对环定好向那么外向树的边也都定向了即都是叶向的边,所以这个连通块的定向方式只有两种。现在统计边中只能贡献给方案 1 和方案 2 的数量 以及可以翻转的边的数量 ,那么我们实际上要把 均分给 使得这两个的最小值尽量大,不妨设 ,容易发现当 时答案是 ,否则是 。
-
当前连通块是树。我们有 种定向方案是钦定 不选定向其他的边,设 是不选 的答案,考察 Alice 的行动,那么把一条边 的贡献设成 相当于把 对 外的子树的所有 ,实际上可以用这个性质加上树上差分通过性质 C,然后我们再考虑 都可以选的我们怎么选,假如存在两个边反向,那么我们将其翻转,两个子树内 不变而路径上 ,一定不劣,因此 Alice 给边定向整体一定是选择一个点 然后所有 方向都指向 。由此枚举 我们得到了一个 的做法。
xor
注意到整个序列都异或的是同一个数,那么考虑一对数,它们相同的数位异或之后也一定相同,比大小其实就是看他们最大公共前缀后的第一位谁大,那么如果异或上的 这一位是 就会改变它们的大小关系,反之则不会。
那么就有一个 的做法了:枚举每一对数并算出比较大小的一位是哪里,开一个计数器 表示比较大小的位在第 位且是不是逆序对的数对数量。
优化也很容易,开一个 01trie 然后插入数,每次查和它相反位的子树大小就可以了。可以优化成 。
Essence of Twilight
交换的一定是逆序对,设交换的是 ,贡献是 ,注意到固定 之后如果有 成为更好的决策,那么一定是要有 的,固定 后 也是类似的,所以能成为决策点的 一定是前缀最大值, 则是后缀最小值,这样子扫描线扫一扫似乎能拿到 的分数。
我们反着考虑,每个位置的数 能对怎样的交换做出贡献:对于 要满足 ,对于 要满足 ,又发现这样的 在前缀最大值上一段连续区间, 也是,所以就变成前缀最大值和后缀最小值序列构成的平面的矩形加,单点最值,扫描线即可,时间复杂度 。
CF1476F Lanterns
考虑令 表示前 个点能覆盖的最大前缀,转移时考虑 怎么选:
-
向右,,前提是 。
-
向左,考虑找到一个 使得 ,这样子说明前 个和 可以覆盖 的全部,那么中间这些点肯定是向右更优,所以 ,这样的 肯定也是最左边的最优,二分出来即可。
时间复杂度 。
冒泡排序交换次数就是逆序对个数,设每个位置的数字向前形成的逆序对是 ,那么有序即 对每个 都成立,考虑冒泡中一次交换 对 的影响,那么就是 ,全局逆序对 。
[USACO18OPEN] Out of Sorts S
求数组最少经过多少轮冒泡后才能有序,这里冒泡是从前往后扫的。
考虑一轮冒泡是什么样子的:选一些数把它们往后移动到某个位置,其他的相对位置不变,并且移动的区域没有交,那么一个数被移动仅当 否则前面会有一个数覆过它,然后一个数从 移到 就使得 前移一位并 ,所以 ,从宏观上来说就是所有 减少 ,因此答案是 。
[NOI Online #1 提高组] 冒泡排序
有了上一题的结论这个题水到爆,用树状数组维护所有 就可以了。
[USACO18OPEN] Out of Sorts G
通过简单的讨论我们能够知道一次双向冒泡可以使得 中一个 的数与后面的一个 的数交换。
[USACO18OPEN] Out of Sorts P
首先进行一个转化,我们注意到计数器加的数是当前数组长度,也就是一个数只要不是单独出来那么它进行一轮冒泡就要对计数器有 的贡献,所以我们不妨对每个数 计算它单独成为一个序列的时间点 ,那么对它们求和就是答案了。
然后考虑如何算 ,注意序列是按照题里面定义的分割线划分的,那么一个数被单独分开仅当它两边都是分割线,所以又转化成分割线出现的时间 ,分割线出现在 处意味着 的数都在 里,其他的都在 里面,那么一个向后的冒泡排序一定是会将在 但 的数中最远的向前挤一位的,所以出现的时间应当是离 最远的在 而 的数与 的距离。
[JOI Open 2018] 冒泡排序 2
超级神题。
首先需要维护的是全局 单点修,直接维护需要查前缀比一个数大的值的个数,后缀比一个数小的数的 加 ,直接维护似乎比较难,但是我们可以找性质!!!
如果存在一对 满足 且 那么 一定是更优的选择,这是显然的,所以我们最终的决策点一定是一些右边全都是比它大的数的 ,这时候我们来一手操作设一个 表示 中 的数的数量那么有 ,然后设 表示全局 的数量,那么我们声称 ,为什么呢?第一个等号成立是显然的,然而对于第二个等号,因为我们最终取的决策点一定是一个右边全都是比它大的数,那么对于它就有 ,对于其他的数有 所以 表示它们不会对最值有影响,因此我们成功地把一个前缀统计弱化成了全局的统计。
直接在权值线段树上以 为键值,同时维护 的 即可,时间复杂度 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话