ACM笔记
文章平均质量分 80
小酒窝.
研一菜鸡一只,欢迎来交流讨论,一起进步!
展开
-
单调栈 & 单调队列 专题
上述操作通过维护单调递增栈,求出了数列中每个数左边第一个比它小的数。同理可以维护单调递减栈,求出数列中每个数左边第一个比它大的数。将枚举顺序转换,从后往前枚举,便能求出数列中每个数右边第一个比它小/大的数。求区间最小值,维护单调递增栈;求区间最大值,维护单调递减栈。把原理搞懂,能够用代码实现之后,这两种算法就掌握了。在以后的题目中,如果需要求每个位置左边/右边第一个比其大/小的元素,就要想到用单调栈;如果需要维护一个移动区间的最值,用单调队列O(n)O(n)O(n)原创 2023-01-05 12:23:36 · 1402 阅读 · 1 评论 -
21台湾省赛 - G. Garden Park(依靠边更新端点)
思考了好久,最后在队友的帮助下终于搞懂了,因为这个一开始加上的非法方案在转移的时候就变成合法的了,一旦转移就说明有了一条边,那么这个一开始加的方案就合法了,转移过去的都是合法方案,所以一开始加的非法方案不会传递给其他点。因为是要满足边权严格递增,一开始想的思路是这样的,把边看成点,边和边建边。之前我写dp转移方案数的题目(比如拓扑序dp,从一个点到该点走过合法路径的方案数)都是把起点 dp[st] 的方案数设为 1,然后后面如果点 y 用点 x 来更新的话,dp[y] 直接加上 dp[x] 就行了。原创 2022-10-08 00:17:13 · 279 阅读 · 0 评论 -
无向图最小环问题
求解无向图最小环问题原创 2022-10-05 23:05:59 · 845 阅读 · 3 评论 -
三分经典例题与真题集合
超多三分经典例题!原创 2022-08-19 16:41:03 · 1039 阅读 · 1 评论 -
数论 —— 整除分块,常见经典例题。
超多经典例题学会整除分块!原创 2022-07-22 22:50:42 · 849 阅读 · 0 评论 -
次小生成树
给定一张 NNN 个点 MMM 条边的无向图,求无向图的(严格)次小生成树。设最小生成树的边权之和为 sumsumsum,严格次小生成树就是指边权之和大于 sumsumsum 的生成树中最小的一个。找一个不在最小生成树的边加进去,肯定会构成一个环,然后替换掉环中除了该边权值最大的一个边,便得到一个新的生成树。取所有这样的生成树中的最小值便是次小生成树。为了保证次小生成树是严格次小,要保证替换掉的最大边权和加进去的边权不相等,如果相等的话,就替换掉次大边权。如果不用保证严格次小,那么直接用最大边权替换就可以原创 2022-07-18 10:43:36 · 1968 阅读 · 0 评论 -
DP 解决 《整数划分问题》
题目模型将数 M 划分成 N 个数,划分成的数可为 0,一共有多少种划分方案?或者说:将数 M 划分成最多 N 个数,一共有多少种划分方案?(划分方案不考虑顺序,例如 2 3 1 和 1 3 2 视为同种方案)思路:定义状态 表示,数字 划分成 个数的方案数。初始化:状态转移:按照分成的 个数中的最小值是否为 0 来划分。Code例题: 鸣人的影分身当考虑顺序时,好像可以用组合数做,这里贴一下我 O(n∗m2)O(n*m^2)O(n∗m2) 的代码:类型二:题目模型将数 N原创 2022-07-07 00:26:29 · 337 阅读 · 0 评论 -
线性dp求解 最长子序列 —— 小题三则
一、最长连续等差数列思路1:dp,O(n)思路2:差分,O(n)二、最长等差子序列思路1:dp,O(nm),m 为 Ai 最大值思路2:dp,O(n^2)三、最长斐波那契子序列思路1:set暴力,O(n^2logmn 2 logm),m为 Ai 最大值思路2:dp,O(n^2)...原创 2022-06-27 16:44:24 · 372 阅读 · 0 评论 -
愤怒的小鸟 ——记忆化搜索,类树形dp,状压dp
Linking题意给定 n 个绿猪,每个绿猪给定第一象限的坐标 (x,y)(x, y)(x,y)。每次可以从原点位置向第一象限发射一只小鸟,飞行轨迹为形如 y=ax2+bxy=ax2+bxy=ax2+bx 的曲线,需满足 a<0a < 0a<0。如果某只小鸟的飞行轨迹经过了点 (xi, yi)(x_i, y_i)(xi, yi),那么第 iii 只小猪就会被消灭掉,小鸟沿着轨迹继续飞行。问,至少需要多少只小鸟能够消灭所有小猪?(1≤n≤18,0<xi,yi<1原创 2022-05-07 21:43:37 · 224 阅读 · 0 评论 -
状态压缩 —— 题型全归纳,超多例题,万字详解。
状态压缩 bfs/dfs/最短路、状态压缩DP,题型全归纳,一篇文章学会状态压缩!原创 2022-04-15 23:10:53 · 949 阅读 · 1 评论 -
dijkstra 求最小环( CCPC桂林 - E. Buy and Delete )
前言:今天做题的时候,碰到一个有向图求最小环问题,发现除了经典的 Floyd求最小环 之外,熟知的求最短路问题的 dijkstra算法 也可以求最小环。实现方式1:回到起点构成环将每一个点都作为起点,跑 dijkstra。对于每个点,从该点出发判断是否能够再回到起点,如果能,说明从该点出发能构成环。因为是跑最短路求得的,所以这个环是 所有从起点出发回到起点的环中 权值最小的一个。将所有点作为起点所得的最小环的最小值 便是 整张图的最小环。每个点都跑一遍 dij,所以 时间复杂度:O(n∗ml原创 2022-04-11 17:18:41 · 2203 阅读 · 0 评论 -
判断最小生成树的唯一性
先来看一个例题:Forsaken喜欢独一无二的树题意:现在给定一个 nnn 个点,mmm 条边的图,每条边 eie_{i}ei 都有一个权值 wiw_{i}wi 。刚开始最小生成树可能不唯一,现在可以删除一些边,使得剩下的边的最小生成树大小不变并且唯一。求删除的边的权值和最小是多少?分析:什么样的边会影响到最小生成树的唯一性呢?kruskal 求最小生成树 是将所有边权从小到大排序,然后判断当前边的两个端点所在连通块是否连通。如果没有连通,那么这条边就需要拿。而此时如果有另外一条边,虽然原创 2022-04-06 22:38:22 · 5428 阅读 · 1 评论 -
PTA - 二叉搜索树的结构 (30 分)——建树,输入处理
二叉搜索树的结构 (30 分)文章目录题意:思路:1. 如何建树?2. 如何解决输入问题?完整Code:经验:题意:定义:二叉搜索树是一棵空树,或者是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。给定一系列互不相等的整数,将它们顺次插入一棵初始为空的二叉搜索树。给出 m 个对结果树的结构的描述,判断给定的描述是否正确。描述有以下6种:A is the原创 2022-04-01 17:29:17 · 2531 阅读 · 0 评论 -
树形dp解决:《节点x选了,其相邻节点选不选问题》
前言:这种 节点x是否挑选对其相邻节点有影响的问题 在树中也很常见,下面是几个经典例题,让我们一起来学习掌握它吧!文章目录例一、没有上司的舞会题意:分析:Code:例二、战略游戏题意:分析:Code:例一、没有上司的舞会题意:原题题意:每个人都有上司,他们之间的关系构成了一棵树。父节点是子节点的直接上司。每个节点有权值 wiw_iwi。先要挑出若干个人参加舞会,每个人都不愿和直接上司一起。问,如何选择能够使得总权值最大?简化题意:一棵树,每个节点有权值 wiw_iwi。要求每条边原创 2022-03-25 21:15:12 · 1222 阅读 · 0 评论 -
经典问题《树的直径》与《树的中心》,详解。
1、定义树的直径: 树上最远的两个节点之间的距离。连接这两点的路径被称为树的最长链。2、如何求出一棵树的直径呢?将任意点看作根节点。对于节点 x 来说:如果最长链在以节点 x 为根的子树中,并且经过节点 x,那么最长链的长度就是从节点 x 到最底端的两个最长路径距离之和。容易想到,最长链一定在一个节点为根的子树中,并且经过该节点,所以我们只需要在所有节点下,找出每个点到最底端的最长的两个距离,维护两个距离和的最大值即可。最终的最大值便是这棵树的直径。从根节点出发,我们可以 dfs 维原创 2022-03-18 18:27:02 · 1977 阅读 · 0 评论 -
Rake It In——搜索解决博弈问题
Rake It In题意:Alice 和 Bob 正在一个 4∗44*44∗4 的棋盘上进行博弈。两个人轮流操作,Alice 先手。操作:选择棋盘上的一块 2∗22*22∗2 的区域,这四个数字和便是这一次操作的分数。然后将这四个数字逆时针旋转 90 度。一共进行 2∗k2*k2∗k 轮操作,每人 kkk 轮。两人操作的分数之和作为最终的分数。Alice 想让最终的分数最大化,而 Bob 想让最终的分数最小化。假设两人都足够聪明,问最终的结果会是多少?(1≤k≤3)(1 \le k \le 3原创 2022-03-15 15:22:13 · 233 阅读 · 0 评论 -
bitset——定义及常用操作。
前言:今天碰见了这个操作,发现在状态压缩的时候特别好用,就整理一下吧。bitset 就相当于一个 只能存储二进制,也就是 0 和 1 的 bool 数组但是可以直接当作一个数进行左移右移,取或取反等二进制操作。如果直接用 bool 数组存储二进制每一位的话,n 位存储复杂度为 O(n),但是用 bitset 的话复杂度会减少到 O(n/32)。所以一般用二进制状态压缩时就会用 bitset。一、定义:对于 bitset 的定义有四种方式:1、直接定义,每一位初始为0:bitset<原创 2022-03-14 20:41:33 · 13252 阅读 · 0 评论 -
bitset 优化dp
简单瞎搞题题意:一共有 n 个数,第 i 个数是 xix_ixi,xix_ixi 可以取 [li,ri][l_i , r_i][li,ri] 中任意的一个值。设 S=∑xi2S = \sum{{x_i}^2}S=∑xi2 ,求 S 种类数。分析:最容易想到的 dp 做法,定义 dp[i, j]:第 i 个位置是否能得到 j。dp[0][0] = 1;for(int i=1;i<=n;i++){ for(int j=1;j<=10000*i;j++) { for(原创 2022-03-14 20:36:35 · 861 阅读 · 0 评论 -
可达性统计 —— 拓扑排序 / 记忆化搜索 + bitset状态压缩
题意:给定一张 N 个点 M 条边的 有向无环图,分别统计从每个点出发能够到达的点的数量。1≤N,M≤300001≤N,M≤300001≤N,M≤30000分析:注意到该图是有向无环图,那么其中的节点就满足拓扑序。对于拓扑序列来说,前面的点一定会指向后面的点。所以我们可以从后往前处理,对于遍历到点 x,其指向的节点的可达点就已经固定了。于是当前点 x 的可达点就是指向节点的所有可达点。但是不能直接将子节点的可达点个数相加,因为子节点间的可达点可能有重复。对于重复的元素只取一个,我们可以想到 或原创 2022-03-14 14:41:15 · 603 阅读 · 0 评论 -
Floyd 解决《最短路最大删边问题》
问题模型:给出 N(N ≤ 500)个点的连通图,问:在不影响任意两点最短距离的情况下,最多能够删除多少条边?分析:什么样的边能够删掉呢?这条边对任何两点的最短距离都没有影响。也就是,对于其端点 a 和 b:从 a 到 b 的最短距离 dist[a,b] 比该边权 w[a,b] 小;从 a 到 b 的最短距离 dist[a,b] 和该边权 w[a,b] 相等,但是可以是从另外的路径过来。那么这条边一样不需要。对于这种情况,可以遍历判断是否存在中转点 k,使得 dist[a,b] = di原创 2022-03-13 18:01:18 · 453 阅读 · 0 评论 -
Floyd 求解《最小环问题》,原理详解。
用最简单易懂的思路帮你搞懂《最小环问题》!原创 2022-03-11 17:21:50 · 1569 阅读 · 5 评论 -
异或性质——前缀异或
昨天遇到一个非常神奇的事情,异或也能维护前缀?有两个例题:例一、子段异或描述:给出长度为n的数列,问 异或值为0的子段一共有多少?思路:之前有一个考前缀和的,求子段和为0的子段个数,做法是这样的:始终取前缀和,如果该位置的前缀和sum之前出现过,那么那次出现的位置到当前位置这一段总和为0。map存下sum出现的次数。遍历到当前位置,map[sum]便是以当前位置结尾的,子段和为0的子段个数。其实这道题也是这个思路:始终取前缀异或,如果当前位置的前缀异或sxor之前出现过,那么那次出现的位置原创 2021-10-10 00:15:54 · 3440 阅读 · 0 评论 -
双端队列_01bfs——附详解典例
我感觉这个算法是作为 dijkstra 等求最短路的优秀替换!时间复杂度可以降到O(m)!原理:如果边权只是0和1的话,启用优先队列未免太浪费资源了!这里用双端队列正是对这个地方的优化,将优先队列O(logn)的时间复杂度降到了O(1)!!过程是这样的:从起点开始,加入队列。while队列非空,取队首元素,用这个节点更新其他节点。如果可以更新的话:1、边权为0,放到队首。(从边权为0......原创 2021-05-15 22:31:35 · 7472 阅读 · 12 评论 -
ST算法 - RMQ(区间最值问题)—— 倍增
带你深入理解 ST算法 的本质——倍增。原创 2021-10-15 10:06:17 · 990 阅读 · 0 评论 -
倒序并查集 —— 逆向思维
题目模型:给出n个点,m条边。k次操作,每次删掉一个点及与其相连的边,给出若干个数对(x,y),问 点x 和 点y 是否在同一连通块中?暴力做法:对于每个数对都跑一遍bfs,超时。需要用并查集。如果按照给出的顺序删点的话,这个点倒是删了,那这个连通块如何更新呢?就没法搞了。想象一下两种状态。一种状态为:正着来删点。原来所有点都没删,然后进行过k-1次操作之后,仅剩最后一个删点没有删,询问两个点x,y是否在同一连通块中。另一种状态为:倒着来加点。连边时,删点不要参与连边。然后加入最后一个操原创 2021-10-14 21:41:29 · 916 阅读 · 0 评论 -
背包问题 模板详解!
一、01背包题目描述:有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。第 i 件物品的体积是 vi,价值是 wi 。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。每件物品只能 不选0,或者选一次1,所以叫做01背包。(好生动 QwQ)—————朴素做法:1、状态表示:f[i][j]表示从前i个物品中选,总体积不超过j的最大价值;2、属性: 最大值;3、状态转移:用“最后一步”来划分:当前物品“选不选”:不选当前物品,那么当.原创 2021-10-14 20:49:51 · 1537 阅读 · 1 评论 -
分层图最短路
今天遇到了一个分层图最短路,虽然是模板题,但是之前没学过,所以来现学一下。什么是分层图?分层图最短路模型:对于一个n个点,m条边的无向图,每条边长度为 wi,求两点间的最短距离。但是有 k 次特权,每次可以将当前边的长度变为 0 (或其他)。在使用不超过 k 次特权的情况下,求两点间的最短距离?遇到这样将边的大小改变的模型,可以构建分层图模型,然后跑最短路。分层图就是把当前点复制几个,放到对应点的下方。有k次特权,就构建k+1层,从当前层连向下一层的边为0,也就是使用了一次特权。最后取这原创 2021-10-06 22:28:34 · 506 阅读 · 0 评论 -
汇总 前缀和 & 差分 的高端操作~
本以为前缀和就是求个前缀数组,然而这几天发现了 前缀和 的另外一些重要性质,解决了许多棘手的问题!在这里汇总一下。原创 2021-08-28 10:55:20 · 1124 阅读 · 1 评论 -
二叉树——根据 中序 和 层序 建树,超详讲解。
模板题传送背景:树和二叉树基本上都有先序、中序、后序、按层遍历等遍历顺序,给定中序和其它一种遍历的序列就可以确定一棵二叉树的结构。假定一棵二叉树一个结点用一个字符描述,现在给出中序和按层遍历的字符串,请构建这棵二叉树。正文:总体思路:与根据先序和中序建树相类似,都是由递归来实现。根据层序遍历的特点,层序序列中第一个元素就是根节点root。确定该节点在中序序列中的位置。则该位置左边的都是左子树,右边都是右子树。左子树的根节点就是root的左孩子,右子树的根节点就是root的右孩子。递原创 2021-05-20 22:20:04 · 5111 阅读 · 6 评论 -
二叉树——根据先序(后序)、中序 建树,超详讲解。
先中和后中的思路相同,这里先以先中举例:思路:通过递归,不断压缩中序和先序序列的长度,从而确定左右子树。根据先序排列的性质,第一个数则是这个序列中所有点的根节点root。确定通过map数组确定该点在中序序列中的位置k。...原创 2021-05-19 22:25:18 · 23311 阅读 · 7 评论 -
floyd——记录路径,原理详解。
Floyd如何记录最短路的路径并输出呢?原创 2021-05-18 21:27:18 · 5079 阅读 · 11 评论 -
二分查找 & 二分答案 万字详解,超多例题,带你学透二分。
很多人对二分很困惑,可能二分的边界很难掌握,也许是判断条件难写... 很幸运,你找到了这篇文章,仔细看下去,这篇文章将带你**学透二分**!!!原创 2021-03-17 17:34:55 · 78408 阅读 · 147 评论 -
二分查找 & 二分答案 ,课后练习题答案。
讲解博客地址:二分查找:1、数的范围:#include<iostream>using namespace std;const int N=100010;int a[N],q,x,n;int main(){ cin>>n>>q; for(int i=0;i<n;i++) cin>>a[i]; while(q--) { cin>>x; int l=0,r=n-1; while(l<r) //找最左边原创 2021-03-17 17:12:03 · 1937 阅读 · 11 评论 -
前缀树(字典树)模板,附典例
前缀树插入、搜索模板:分别给出n,m个字符串,分别判断m个字符串是否在n个字符串中(子串不算)#include<bits/stdc++.h>using namespace std;int tree[100][100],isEnd[100],cnt,root; //cnt对每个字符编号; int T1,T2;void insert(string a){ root=0; for(int i=0;i<a.size();i++) { int t=a[i]-'a'; if原创 2021-02-17 17:09:36 · 242 阅读 · 0 评论 -
前缀和&差分 精讲(一维、二维、附例题!)
这篇文章是我寻找众多博客总结归纳的,还有找到的部分经典例题,相信看完的你一定会有新的感悟!加油!一、一维前缀和一维的前缀和数组sum[ i ]就是存的是 前i个数的总和 。那么x到y区间的总和就是 sum[ y ] - sum[ x ]应用:1、求一个数前面的所有数的和:递推;2、求较多区间( l , r )之间的数的和:求前缀和之后 ans=a[r]-a[l-1];例:HJ浇花、color the ball;3、多组数据,每组数据都用同一总数组来操作,如果一组数据一组数据遍历的话很容易原创 2021-02-01 11:28:40 · 1245 阅读 · 0 评论 -
归并排序模板
#include<iostream>using namespace std;void copy(int b[],int a[],int left,int right){ for(int i=left;i<=right;i++) a[i]=b[i];}void merge(int a[],int b[],int left,int mid,int right){ int i=left,j=mid+1,k=left; while(i<=mid&&j<原创 2021-02-09 11:43:47 · 188 阅读 · 0 评论