补题集合
数论,dp
思路:
令A为一个正整数序列,
- 将
分解质因数, = * ... - 则LCM(A)就是由每一个p的指数取max组成的
如果子序列合法,那么子序列中每个数分解质因数之后,至少有一个数的p的指数和M的相同。然后我们将相同记为1,那么就将题目转化成从n个数中选一些数使得他们的异或值为Target的方案数,因为数组开不下所以用滚动数组优化,
概率dp,记忆化搜索
思路:
由于操作二是一个概率性问题,所以定义dp[n] 为让n变为0的最小期望花费,每次都是操作二选一所以不难推出如下状态转换
- 如果选择操作一:dp[n] = dp[n / a] + x;
- 如果选择操作二:dp[n] = E(X) + y; E(X)表示骰子要出来之后的平均期望。
trick:
- 因为n的范围在
,直接开数字组会爆,所以选择map加dfs记忆化搜索 - 代码实现过程中,发现如果骰子摇出来的是1,会导致死递归(n一直不变),所以在算E(X)的时候单独把1拎出来
换根dp,典题
思路:
如果是固定根节点的话只需要dfs一下整棵树就可以在
- 假设当前根节点为u,那么从父节点fa转到u,答案的变化就是 ans[u] = ans[fa] - A(以u为根节点的子树中c的和) + B(除了A以外的c的和) = ans[fa] + 总和 - 以u为根节点的子树
- 所以先预处理出来c的总和sum 和 siz[i]: 以i为根节点的子树中c的和
- 然后利用1中的状态转移进行dp,初始化就是dp[1], dp[1]可以写dfs搜一下
trick:
证明1 : 根从fa -> u的话,发现以u为根节点的子树中所有节点到根的距离减少一,意味着相对ans[fa]减少了siz[u],但是其它点到根的距离增加一,所以要再加上这部分的和
类似题
类似题
类似题
类似题
切尔雪夫转曼哈顿,快速算区间内两两点的曼哈顿距离之和
思路
题目给的是每次可以沿着对角线移动,这样算起来很不方便因为答案可能带根号而且复杂度
假设当前坐标为
这样求出来坐标为
回文长度,思维
思路
由题意易得
数论,扩展欧几里得
思路
计算几何,求面积技巧
思路:
先定义一下什么是凸多边形,就是把多边形一条边无限延申后,整个图像只在直线的一边出现。由此本题要求的最小的凸多边形就是三角形,数据范围很小所以直接暴力枚举三个点。问题关键在于如何快速求三角形的面积,因为本题只给出了点的信息,所以可以利用叉积的方式求三角形面积,但是面积可能是浮点数,为了保证精度问题,所以我们最后再除以二
二分,思维
思路
通读题面后易得,某一条路径对应的答案其实就是路径外部的最小点,若某一答案为ans,则意味着[0, ans - 1]中所有的点都应该在路径上,思考发现答案具有二分性因为如果ans为答案则ans - 1肯定也是答案,因为[0, ans - 2]是[0, ans - 1]的子集。所以可以考虑二分答案,check函数是关键。因为每次只能向下或向右移动,所以路径上的点的横纵坐标都应该是单调递增,所以可以枚举其中一个然后判断另一个是不是单调递增的从而判断check是否合法
树上二分
思路
当我们断[u, fa]这条边断开时,只有u的祖宗节点才会受到影响而且离u越近越受到影响越大,所以由u的祖宗节点组成的死域点集合是存在二分性的,断掉这条边之后离u比较近的一些点祖宗死域点可能会突变成非死域点。所以可以dfs一下断开每条边所能解救的最多死域点,然后答案就是一条边不断的死域点个数减去这个maxx。
trick
要考虑回溯的情况。
思维,正难则反
思路
- 先按左端点排序,然后用线段树做区间加,区间查询最大。注意离散化
- 直接算相交区间是比较难的限制条件比较多,所以先算全部的然后再减去不相交的,不相交就只需满足l[i] > r[j]则两区间不相交,先分别对左右端点排序然后双指针扫一遍
状压DP,bfs
思路
把整个地图的鱼看成一个状态,每次放一个炸弹就会改变这个状态,然后就抽象出一个搜索树问题就变成了找根节点到0状态
的最短路显然bfs可做。关键是怎么把地图存下来,可以观察到每个鱼塘最多只有三条鱼,而且最多只有十个鱼塘。所以可以把整个地图的鱼压缩成一个四进制数,形如init = a[0] * 1 + a[1] * 4 + a[2] * 16...,含义为第i个鱼塘有a[i]条鱼。转移的时候就暴力枚举在每个点放炸弹。
tirck
- 因为地图很大,但是鱼塘很少。所以不是每个点都有意义,只有鱼塘的上下左右以及自己这五个点放炸弹才有意义,所以只需要在这些点上进行转移
- 在转移时状态用十进制表示,枚举的时候要变回四进制来判断第i个鱼塘还有没有鱼,形如a[1]位置减少一条鱼那么对应十进制状态要减少4
推公式,经典套路
思路
= n * ,易得这是个等比数列求和公式,化简之后用快速幂就可以了
数位性质
思路
- 令 n =
* 10 + 易得 k * n = k * * 10 + k * , D(k * n) = k * + k * - k * D(n) = k *
+ k * - 由上式可知,k *
不能超过10,不然会发生进位导致结果不相等,所以每一位取值在[0, 9],所以当位数为r
时可选数字为
计数,字典树
思路
直接考虑答案,如果答案是abc
那就说明最多可选的字符串cnt = 所有以abc开头的 + abc*
开头的各选一个,如果 cnt >= k那么说明答案就是abc。直接暴力枚举
trick
代码感觉比较难写,因为要集合的LCP最大,所以那些长度小于abc的也可以要选上
多源bfs
思路
当可忍受的辣度为
所以可以开一个数组dp[i][j]来维护当阈值为j
时i
到合法点的最短路,因为阈值最多不超过100所以只需要跑100遍bfs
trick
类似题还有二进制,bfs找连通块
- (u, v)是否存在一条路径的与值大于等于V
- (u, v)是否存在一条路径的与值等于V
显然问题一可以通过多次求解问题二来解决,所以可以通过枚举[V, )次问题二来得到问题一的答案,显然问题二中可走的边一定满足v & va == va
,在这个条件下整张图有些边就会变得无效,即图将变成若干个连通块。显然只有在一个连通块中的点才可以互相到达。但是直接枚举的话会超时,考虑&
的性质发现,若a > b则a的二进制和b的二进制一定有一段相同的前缀,且第一个不一样的地方必须是a[i] = 1, b[i] = 0。所以枚举的时候每次都增加一个lowbit(i)即可。
总结
这类问题都有一个特征就是题面中都会存在一个阈值,随着阈值的改变图中的点或者边将会发生改变。在第一个题中随着
第二类斯特林数
思路
我们把m个数展开成二进制,可以发现每列只能有一个1
,每一行可以有多个1
。一共有n
个1
也就是说有n
列。等价于将n
个1
放进m
个盒子里面,不能有空盒子。直接套用第二类斯特林数
位运算技巧,枚举
思路
令最后的总重量为C,则 C < m,说明C 和 m有一段相同的前缀...,所以我们可以枚举把m中的哪一位1改成0。在这样的m下w[i]和m前缀必须相同,后缀随便取
trick
- 后缀随便取 => xxx1111 & xxxaaa = xxxaaa
割边,生成树
思路
为了让点对最少,肯定优先断割边。这样一个连通图就变成两个连通图,点对就减少了
trick
在枚举割边时,我们需要的是当前这条割边的儿子的子树大小。因为在生成树时是从小到大枚举,所以小的是父亲,大的是儿子
DP,bfs
思路
p - 1
,我们可以发现后面一部分模出来全是1,所以
有理数,进制,dfs
思路
k
进制下为有理数等价于
trick
由数据范围可知x的一定不会超过100,所以直接令x为100
记忆化搜索
思路
对于一条合法光路,路上每一点在第一次搜索时答案就已经确定了。所以每个点每个方向最多只会被搜一次。可以先预处理出来整个图的边界光线照射的答案,然后O(1)回答
trick
- 光路可能是环,所以dfs的退出条件有两个。
- 搜出的光线是正向的,但是答案要反着记。
换根DP
思路
很明显的换根DP,关键在于如何定义状态和状态转移,令DP[u]表示以u为根节点的子树中不合法的边的数量,那么u如果为合法方案则DP[son] = 0
,并且edge(u, v)为合法边。我们考虑根从u->son,首先就有DP[u] -= DP[son] + (edge(u, v))
,
DP[v] += DP[u] + (edfe(v, u))。
trick
在dping时要注意恢复现场,因为当转移到下一个儿子时,父亲要保持不变
对顶堆,中位数
思路
a[i + 1] - a[i] = (i + 1) - i,所以先把数组的每个数减去下标,问题就转化成了在最多k次操作下最长一段值相同的子数组。将区间变成相同的数的最小代价就是变成中位数。所以用对顶堆来维护区间中位数以及代价,然后用双指针来找最长区间
枚举
思路
首先想到暴力枚举x, y。但是这样复杂度O(
预处理
本文作者:自动机
本文链接:https://www.cnblogs.com/monituihuo/p/18147035
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步