随笔分类 - 数据结构与算法
摘要:(目录) 试题下载 试题 A: 美丽的 2 本题总分:5 分 【问题描述】 小蓝特别喜欢 2,今年是公元 2020 年,他特别高兴。 他很好奇,在公元 1 年到公元 2020 年(包含)中,有多少个年份的数位中 包含数字 2? 【我的题解】 数位分离,水题了。
阅读全文
摘要:(目录) 试题下载 试题 A: 跑步训练 本题总分:5 分 【问题描述】 小明要做一个跑步训练。 初始时,小明充满体力,体力值计为 10000 。如果小明跑步,每分钟损耗 600 的体力。如果小明休息,每分钟增加 300 的体力。体力的损耗和增加都是均匀变化的。 小明打算跑一
阅读全文
摘要:题目传送门 sol:因为查询的点一共最多只有100000个。若当本次查询的点比较少,小于√100000,那我们可以枚举起始点u和终点v,若u,v之间有边,则用并查集将u,v节点合并,最后统计有多少个联通块;若当本次查询的点比较多,大于$\sqrt{100000
阅读全文
摘要:题目传送门 sol:树剖解决,我们只维护每个节点和重儿子的边权,那么当一个节点权值改变时,也只需要修改该节点和其重儿子的边权,若该节点是其父亲节点的重儿子,则多修改一条该节点和其父亲节点的边权。查询操作时,若该节点不是父亲节点的重儿子,则暴力计算一次该节点和父亲节点的边权。 树链剖分 #includ
阅读全文
摘要:题目传送门 sol:有三种情况无法构造满足条件的答案。 出现同一行(列)的两个'#'之间隔着一段'.'的情况,比如样例2。如果两个'#'之间隔着一段'.',那么在这一行(列)就无法放置南磁铁,因为'#'代表北磁铁可以到达,若在这一行(列)任意位置放置南磁铁,会导致这两个'#'中的至少一个北磁铁被吸到
阅读全文
摘要:题目传送门 sol:树形dp,用dp[u]表示节点u代表的子树合法染色方案的数量,若u节点是黑色,则所有儿子随意,产生的方案数为∏dp[v],v∈son[u];若u节点是白色,则含有黑节点的儿子最多只能有一个,也可以没有。因为dp[v]里必有一种方案是整颗
阅读全文
摘要:题目传送门 A .Nastya and Rice pro:问能否找出n个区间[a−b,a+b]内的数,满足和在区间[c−d,c+d]之内。 sol:最小的和是n∗(a−b),如果n∗(a−b)>c+d,结果为"NO";最大的和是$n *
阅读全文
摘要:题目传送门 sol:首先我们考虑在一个长度为n的序列里只有一个数出现了两次其他数都只出现了一次,那么在序列中出现过的数就有n−1个。而这些数的范围是[1,m],从[1,m]里选n−1个不同的数的方案数为Cn−1m。这n−1个数里最大的数不能
阅读全文
摘要:题目传送门 sol:假如把这题树上这个条件改成序列,那么对于操作2,求某区间[l,r]所有连续子序列的异或和。观察得出若r−l+1是偶数,则答案是[l,r]区间的异或和。否则,答案是[l,r]区间内下标奇偶性与l不同的元素的异或和。那么可以用三颗线段树来分别维护奇数
阅读全文
摘要:题目传送门 官方题解传送门 A .操作序列 sol:如果STL熟悉,那么就是一道模拟题。就是输入有点奇葩。但是看了官方题解中提到了平衡树。嗯,没错,map和set的底层都是平衡树。红黑树不会,平衡树觉得还是fhq-treap好敲。所以,提供一份map的解法和一份fhq-treap的解法。 map #
阅读全文
摘要:题目传送门 sol:可以用线段树来维护,线段树的节点除了标配的l和r同时记录该区间link的个数记为cnt,该区间link点的和记为sum,该区间题目中所谓的能量记为dis。然后cnt和sum就直接两个儿子相加就好,dis还要另外加上$segTree[rs].
阅读全文
摘要:题目传送门 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,还是要解决跳fail边产生的重复访问,但是这次用last边已经不行了,只能拿76分。我们把跳fail边的过程放到串扫描完之后一次性进行。 AC自动机 #include <bits/stdc++.h> using nam
阅读全文
摘要:题目传送门 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,在fail边的基础上再加一个last边,指向真正有效的节点,跳fail边改成跳last边来跳过无效点。 AC自动机 #include <bits/stdc++.h> using namespace std; typed
阅读全文
摘要:题目传送门 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:标准AC自动机,注意不能重复跳fail边,像"aaaaaaa...aaaaaaaa"这样的数据每跳一次fail边只往上走了一层。 AC自动机 #include <bits/stdc++.h> using namespace std
阅读全文
摘要:题目传送门 sol:先通过AC自动机构建字典,用dp[i]表示长串前i位的最小代价,若有一个单词s是长串的前i项的后缀,那么可以用dp[i−len(s)]+val(s)转移到dp[i]。 AC自动机 #include <bits/stdc++.h> using nam
阅读全文
摘要:题目传送门 sol:二分答案K,算大于K的乘积有多少个。关键在于怎么算这个个数,官方题解上给出的复杂度是O(nlogn),那么计算个数的复杂度是O(n)的。感觉写着有点困难,自己写了一个复杂度是O(nlog2n),也够AC了。有正有负,控制边界有点难度。 二分答案 #inc
阅读全文
摘要:题目传送门 sol:根据题意建立流量网络然后跑网络流,这两天刚学的网络流,练练手。 网络最大流 #include <bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> PII; const
阅读全文
摘要:题目传送门 sol:题目的数据范围就是对解决方案的一种提示,原先以为当数据范围只有20的时候都是dfs或者二进制枚举这种,从这题了解到还有状压dp。不解释了,反正就是状压dp,做的不多,记录一下。 状压dp #include <bits/stdc++.h> using namespace std
阅读全文
摘要:题目传送门 sol:每个下标都有选和不选两种情况,所以总方案数是2n,在n最大是100000的情况下不符合要求。可以这样想,假设ip=k有符合题目要求的解,还有一个整数j,j不是i的整次幂,i也不是j的整次幂,那么jp=k不可能成立,所以我们
阅读全文
摘要:题目传送门 sol:根据题意,可以把字符串截成两段,要求两段中最大的两个回文串相加最大的方案,于是跑马拉车维护一个前缀,再倒着跑马拉车维护后缀。因为最优方案肯定是在两个字母之间截,所以最后只考虑在'#'位置截断的情况 马拉车 #include <bits/stdc++.h> using namesp
阅读全文