CH
qq_38232157
这个作者很懒,什么都没留下…
展开
-
CH 6201 走廊泼水节(进阶指南,kruskal最小生成树)
算法竞赛进阶指南, 366页, kruskal 算法本题要点:1、n个点的树, 有 n - 1条边。要补充 n * (n - 1) / 2 - (n - 1) 条边,然后变成一个完全图(一共 n * (n - 1) / 2 条边)。要求原来的树,是完全图唯一的最小生成树。显然,补充的每一条边(x, y),都比从 x 点 和y 点出发的边都要长;2、根据 kruskal 算法进行计算:当处理到边 (x, y, z) 的时候,x点 所在的集合 为 s[x], y点所在的集合为 s[y]。显然,两个原创 2020-06-14 15:59:08 · 147 阅读 · 1 评论 -
CH_0802 占卜DIY(算法竞赛进阶指南,stl,模拟)
算法竞赛进阶指南48页,stl,模拟本题要点:1、用 deque 来存放每一对扑克, 因为 deque 可以两头放数据。 用数字,表示扑克的大小,deque2、4 条命,剩下的就是模拟运行过程。3、题目要求的是,每堆牌, 4张都要正面朝上,因此,用数组 turn[i] 来存放 第 i 堆正面朝上的次数。#include <cstdio>#include <cstring>#include <iostream>#include <vector>原创 2020-09-12 14:48:58 · 153 阅读 · 0 评论 -
CH5202 自然数拆分Lunatic版(算法竞赛进阶指南,完全背包)
算法竞赛进阶指南,278页,完全背包本题要点:1、把完全背包的代码改改即可。常规的完全背包:有n个物品,每个物品的体积是v[i], 价值是w[i], 求装到大小为m的大背包,能获得的最大价值(每个物品可以选任意多次)。f[j]表示到小为i的背包,最多能获得的最大价值f[j] = max(f[j], f[j - v[i]] + w[i]); // j从小到大扫描2、题目意思转换:有n个物品,每个物品的体积是v[i], 价值是1, 求装到大小为m的大背包,一共有多少种装法。f[j]表示到小为i的原创 2020-07-02 22:48:18 · 176 阅读 · 0 评论 -
CH5101 LCIS(算法竞赛进阶指南,线性dp)
算法竞赛进阶指南,266页,线性dp本题要点:1、转态表示f[i][j], 表示在 a[1] ~ a[i] 范围内,b[1] ~ b[j] 范围内,以b[j]结尾的LCIS 的长度2、转态转移方程a[i] != b[j], f[i][j] = f[i - 1][j];a[i] == b[j], f[i][j] = 1 + max{f[i - 1][k], 0 <= k < j}#include <cstdio>#include <cstring>#in原创 2020-07-02 20:34:54 · 141 阅读 · 0 评论 -
CH 5201 数字组合(算法竞赛进阶指南,01背包)
算法竞赛进阶指南,277页,01背包本题要点:1、把01背包的代码改改即可。常规的01背包:有n个背包,每个物品的体积是v[i], 价值是w[i], 求装到大小为m的大背包,能获得的最大价值。f[j]表示到小为i的背包,最多能获得的最大价值f[j] = max(f[j], f[j - v[i]] + w[i]);2、题目意思转换:有n个背包,每个物品的体积是v[i], 价值是1, 求装到大小为m的大背包,一共有多少种装法。f[j]表示到小为i的背包, 一共有多少种装法:f[j] = f[j原创 2020-07-02 20:32:54 · 266 阅读 · 0 评论 -
CH 3101 阶乘分解(算法竞赛进阶指南,阶乘的素因子分解)
算法竞赛进阶指南,138页,阶乘的素因子分解本题要点:1、直接套用阶乘的质因数分解公式, n的阶乘中,n! 含有素数p 的因子个数为[n / p] + [n / p^2] + [n / p^3] + … + [n / p^k] + …2、先用线性筛法打个素数表, 然后扫描素数表,对于每一个 p <= n 的素数,执行上面的公式计算素因子的个数。3、 比较 p^k 和 n的大小关系,使用 long long#include <cstdio>#include <cstri原创 2020-07-01 11:18:51 · 302 阅读 · 0 评论 -
CH 6802 車的放置 (算法竞赛进阶指南,二分图最大匹配, 增广路算法)
算法竞赛进阶指南, 427页,二分图最大匹配本题要点:1、二分图最大匹配增广路算法的模板题。本题中,MaxN= 200,可以用邻接矩阵来存储图。二分图的左部是 n 行, 右部是 m列。行与行之间没有连线,列与列之间也没有连线。每行, 每列只能放一个车,格子(i, j) 放了车,相当于第i行与第j列有连线。2、增广路算法:扫描左部的每一个点x,寻找一个匹配的右部节点y。 y满足一下的条件a) y 本身是非匹配点b) y本身与x1 匹配,但从 x1 出发,能找到另外一个 y1 与之匹配, 此时路径原创 2020-06-28 00:36:30 · 145 阅读 · 0 评论 -
CH 4201 楼兰图腾(算法竞赛进阶指南, 树状数组)
算法竞赛进阶指南,205页,树状数组本题要点:1、利用树状数组求逆序数, 顺序数:以求 “V” 子图腾为例子, Right[i]表示 a[i] 的后面有几个数比它大, Left[i]表示a[i]前面有几个数比它大a) 倒叙扫描数组a,利用树状数组去除每个a[i] 后边有几个数比它大, 记为 Right[i]b) 顺序扫描数组a,利用树状数组去除每个a[i] 前面边有几个数比它大, 记为 Left[i]答案就是 sum{Right[i] * Left[i]}, 1 <= i <= n原创 2020-06-20 14:58:57 · 181 阅读 · 0 评论 -
CH 4302 Interval GCD(进阶指南,线段树,树状数组)
算法竞赛进阶指南,215页, 线段树,树状数组本题要点:1、最大公约数 gcd(x, y) = gcd(x, y - x), 三个数的情况:gcd(x, y, z) = gcd(x, y - x, z - y), 联想到差分数组, 令 b[i] = a[i] - a[i - 1],用线段树维护 数组b 的区间最大公约数,a) 每次 询问 “Q L R” ,就是要求出 gcd(a[L], ask(1, L + 1, R))注意, L == R 的情况,直接返回 a[L]即可(也就是gcd(a[L]原创 2020-06-20 00:05:35 · 156 阅读 · 0 评论 -
CH 4301 Can you answer on these queries III(进阶指南,线段树)
算法竞赛进阶指南,215页, 线段树本题要点:1、线段树的每个节点维护的信息线段的左右端点:L 和 Rdat : 区间最大连续子段和sum : 区间所有数的总和lmax: 紧靠左端的最大连续子段的总和rmax: 紧靠右端的最大连续子段的总和2、线段树 的父节点 p 和左孩子 2 * p, 右孩子 2 * p + 1 的信息关系, 在build 和 change函数中维护好节点的信息t[p].sum = t[2 * p].sum + t[2 * p + 1].sum;t[p].lmax原创 2020-06-19 16:59:53 · 143 阅读 · 0 评论 -
CH 1801 括号画家(进阶指南,栈)
算法竞赛进阶指南,90页,栈本题要点:1、 用栈来模拟,1)遇到左括号,直接入栈;1)遇到右括号,如果栈顶的括号与之配对,则弹出栈顶的括号;如果不配对,则将右括号入栈(这个右括号不可能有配对的左括号了)2、求最长的括号序列:每个括号都有一个id号(在字符串中的顺序), 右括号(当前 now)与栈顶括号配对时候, 先弹出栈顶的左括号,此时栈顶(top) 的id和 now 的id之差,就是美观序列的长度;//当然,注意栈为空的情况#include <cstdio>#includ原创 2020-06-13 15:23:45 · 150 阅读 · 0 评论 -
CH 1802 表达式计算4(进阶指南,栈, 中序和后续表达式)
算法竞赛进阶指南,90页,栈本题要点:1、一个数字可能包含多位数字,预先对字符串进行处理,得到中序表达式 queue inOrder;我这里没有考虑到负数的情况;2、中序表达式,通过栈进行转化为后续表达式:运算符的优先级, 左括号 < 加减 < 乘除 < 乘方具体步骤:1) 遇到一个数字,输出到后续表达式;2) 左括号,压栈;3) 遇到右括号,弹栈,运算符输出到后续表达值,直到弹出右括号(右括号不输出到后续表达式);4) 遇到运算符(new), 和栈顶运算符(top)比原创 2020-06-13 14:11:25 · 152 阅读 · 0 评论 -
CH 0805 防线(进阶指南,二分)
算法竞赛进阶指南,48页,二分本题要点:1、 本题的关键数据, 所有的坐标点上,最多只有一个数是奇数;然后计算小于等于某个坐标点 x,含有的所有等差数列 st[i], ed[i], d[i] (1 <= i <= n)出现过的点的总和。具体某个等差数列st[i], ed[i], d[i], 在小于等于x的坐标点出现的次数:(min(ed[i], x) - st[i] ) / d[i] + 1;2、二分所有的坐标点,注意坐标点的最大值 为 2^31 - 1。直接使用 long long原创 2020-06-12 22:28:12 · 160 阅读 · 0 评论 -
CH 1806 Matrix (进阶指南,字符串hash)
算法竞赛进阶指南,91页,字符串hash本题要点:0、 字符串哈希值,可以有一个字符串的所有的前缀字符串相减得到h[R] - h[L - 1] * p_pow[R - L + 1];1、 求某一个小矩阵 (a * b )是否在 一个大矩阵(n * m)中匹配,求出大矩阵中所有的尺寸为 a * b 的子矩阵的哈希值, 放在一个 unordered_set 中, 然后后面的 q 次查询,每次在集合中查找是否存在该矩阵的哈希值2、 当前小矩阵s 从第i行, 第j列开始, 也就是行数: [i, i原创 2020-06-06 15:31:48 · 166 阅读 · 0 评论 -
CH 1201 最大子序和(进阶指南, 单调队列)
算法竞赛进阶指南,58页,单调队列本题要点:1、长度最大值为m的滑动窗口内,所有数的和可以用 前缀和的差值来表示。当右端点 i固定, 左边 i - m ~ i - 1 这m下标中,取值 k < j(i - m <= k < j <= i - 1)如果 sum[k] <= s[j], 那么 sum[i] - sum[j] >= sum[i] - sum[k], j的生存时间比k长;2、用一个队列来存 一个单调的前缀和的下标,(下标位置递增,前缀和也递增),每一原创 2020-06-05 17:39:40 · 181 阅读 · 0 评论 -
CH 1402 后缀数组(进阶指南,字符串hash,二分)
算法竞赛进阶指南,69页, 字符串哈希,二分本题要点:1、通过字符串哈希来判断字符串的所有子字符串是否相等;使用sort 排序,n个字符串排序的比较次数 O(n * log(n)), 长度为n的字符串,比较的次数是n,如果暴力使用sort ,总的时间复杂度为 O(n^2 * log(n));2、如果通过二分法来判断连个字符串是否相等,时间复杂度为 O(log(n)) ,总的复杂度为 O(n * log(n) * log(n));对于两个后缀字符串,从下标 p和q开始,计算出其公共前缀的长度为原创 2020-06-05 17:33:22 · 158 阅读 · 0 评论 -
CH 1401 兔子与兔子(进阶指南,字符串hash)
算法竞赛进阶指南,68 页, 字符串哈希本题要点:1、 求出字符串 str 的所有的前缀字符串的哈希值,那么,str的所有子串的哈希值都可以在 O(1)的时间内计算出来2、 计算公式:子串区间 [L, R]pre[R] - pre[L - 1] * p^ (R - L + 1)#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int p =原创 2020-06-05 17:26:58 · 143 阅读 · 0 评论 -
CH 0503 奇数码问题(进阶指南, 逆序数,归并)
算法竞赛进阶指南,38 页, 排序, 归并求逆序数本题要点:1、 不考虑空格,把每一个数字写到一个数组 a 上空格与一个数字左右交换,逆序数不变。空格与一个数字上下交换,相当于把某个数字 (比如 a)往前移动了 n - 1 个位置或则往后移动了 n - 1 个位置。2、 这里以 a 往前移动了 n - 1 个位置为例,这n - 1 个数,假设有x个大于a , y个小于a(x + y == n - 1),移动前的逆序数: 不变的部分 + x移动后的逆序数: 不变的部分 + y两种转态的逆序数的原创 2020-05-31 16:19:11 · 254 阅读 · 0 评论 -
CH 0502 七夕祭 (进阶指南,前缀和,中位数)
算法经竞赛进阶指南,34页, 中位数, 前缀和本题要点:1、 左右交换,行的摊点数不变,列的摊点数改变。同理,上下交换, 列的摊点数不变,行的摊点数改变。因此,行的摊点和列的摊点, 可以看做是独立的两个事件;2、这里以行的摊点为例子;row[i] 表示第i行有多少摊点;sum_x 一共有多少个摊点,一共n行。如果,sum_x % n == 0, 那么上下交换,一定可以使得,每一行的摊点数一样。每一行有 t = sum_x / n 个摊点;3、 求解过程,类似于 “均分纸牌”。详细看书:数原创 2020-05-31 15:58:42 · 184 阅读 · 0 评论 -
CH 0601 Genius ACM(进阶指南,倍增,归并)
算法竞赛进阶指南,40 页,倍增本题要点:0、 要求每两个数的差的平方和最大,需要配对,最大配最小,次大配次小,依次类推1、开2个数组:a[MaxN] :这个数组存原始数据,b[MaxN] :这个数组,存放每一段已经排好序的数据;c[MaxN] :归并排序用的临时数组;2、 倍增:寻找每一段满足 差的平方和 sum <= k 的最长区间范围,L 和 R, 每次增加一段 p,一开始 p = 1, 如果区间 [L, R + p]满足条件,那么 p *= 2, 否则 p /= 2;3 、原创 2020-05-30 17:16:04 · 295 阅读 · 0 评论 -
CH 2101 可达性统计(进阶指南, 位运算,拓扑排序)
算法竞赛进阶指南, 99 页本题要点:1、有向无环图,拓扑排序之后,得到拓扑序列 top_order[MaxN]。top_order[i] 可以到达的点 假设为 f(top_order[i]),等于 top_order[i]所有相邻的点 (假设其中任意一点为j)可以到达的点f(j)的并集。因此,从后往前扫描拓扑序列,依次求并集。2、 用c++的 bitset 模板来处理位运算。参考 https://www.cnblogs.com/magisk/p/8809922.html构造函数 : bit.s原创 2020-05-29 11:44:38 · 197 阅读 · 0 评论 -
CH 2601 电路维修(进阶指南,广搜)
算法竞赛进阶指南,120页,双端队列应用到 广搜本题要点:1、题目输入的是 row * col 的 格子, 每个格子表示一条边。而每个格子的顶点,的范围是 0 <= i <= row, 0 <= j <= col;int dist[MaxN][MaxN]; // dist[i][j] 表示顶点(i, j) 到 起点(0, 0) 之间的距离, 显然,dist[0][0];2、 用双端队列存储每一个顶点, 先把起点 (0, 0) 放到 队列中, 如果队列不为空,那么队头出列,原创 2020-05-28 14:47:50 · 199 阅读 · 0 评论 -
CH 2401 送礼物(进阶指南,双向搜索)
算法竞赛进阶指南,111 页,双向搜索,先搜一半,再搜一半本题要点:1、数据直接用 long long 来存,避免溢出麻烦2、从大到小排序,先处理前一半的数据, 看看可以组合出来哪些 数的和是 小于等于 w的( 和 <= w)。用 vector 存储这些和,去重,排序。这里使用vector的 unique 函数 和erase 函数。3、 处理后面一半,得到若干数的和 为sum(sum <= w)。然后在 vector 中二分查找, 最大的一个数 k 使得, k + sum <=原创 2020-05-27 23:41:58 · 208 阅读 · 0 评论 -
CH 2501 矩阵距离(进阶指南,广搜)
算法竞赛进阶指南,115 页, 广搜的常规题目本题要点:1、用 pair 存储坐标点(x和y坐标), 先把矩阵A中的 1 点的曼哈顿距离设置为0, 其余的点设置为无穷大2、先把所有的 曼哈顿距离为0的点(x, y)加入队列queue,然后其上下左右四个坐标点(x + dx[i], y + dy[i]) ,如果不超出范围,并且距离能更新为一个更小的值,就更新该点(x + dx[i], y + dy[i]),并把它加入队列中;#include <cstdio>#include <c原创 2020-05-27 17:18:48 · 149 阅读 · 0 评论 -
CH_2201 小猫爬山 (进阶指南,搜索)
1、 用一个数组,cab[MaxN], 记录每一辆车上所有猫的重量;void dfs(int now, int cnt) //now 表示当前已经有多少只猫上车,车的数量是 cnt;cab[i] += cat[now]; //选择某一辆车 cab[i] 辆装当前猫 cat[now]dfs(now + 1, cnt); //递归cab[i] -= cat[now]; //递归出来,车 cab[i] 辆不装当前猫 cat[now]2、 先排序,从大到小,优先安排重量大的猫上车;3、 对于cnt原创 2020-05-20 15:14:31 · 336 阅读 · 0 评论