算法阶段总结1
阶段总结
通过今天晚上的这场div2我深刻的意识到,光是会找窍门是远远不够的,你得会基础的建图,dp,高级数据结构,你这样才可以不断的提升自己,不可以一直在一个阶段停留下去,构造题可以刷下去,但是要开始复习之前的东西和新算法的学习了。为此这篇总结,我将以我现在的代码风格写出算法基础课的所有算法模板。
1.快速排序
// Problem: 快速排序
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/787/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// Author:lvzihao521
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>using namespace std;
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using pii = pair<i64, i64>;void solve() {int n;cin >> n;vector<int> a(n);for (int i = 0; i < n; i ++) {cin >> a[i];}function<void(vector<int> &a, int l, int r)> quick_sort = [&](vector<int> &a, int l, int r) -> void {if (l >= r) {return ;}int i = l - 1, j = r + 1, x = a[l + r >> 1];while (i < j) {do {i ++;} while (a[i] < x);do {j --;} while (a[j] > x);if (i < j) {swap(a[i], a[j]);}}quick_sort(a, l, j);quick_sort(a, j + 1, r);};quick_sort(a, 0, n - 1);for (int i = 0; i < n; i ++) {cout << a[i] << " \n"[i == n - 1];}
}int main() {int t;t = 1;while (t --) {solve();}return 0;
} 
第k个数
// Problem: 第k个数
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/788/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// Author:lvzihao521
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>using namespace std;
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using pii = pair<i64, i64>;void solve() {int n, k;cin >> n >> k;vector<int> a(n);for (int i = 0; i < n; i ++) {cin >> a[i];}function<int(int l, int r, int k)> quick_sort = [&](int l, int r, int k) -> int {if (l >= r) {return a[l];}int i = l - 1, j = r + 1, x = a[l + r >> 1];while (i < j) {do {i ++;} while (a[i] < x);do {j --;} while (a[j] > x);if (i < j) {swap(a[i], a[j]);}}if (j - l + 1 >= k) {return quick_sort(l, j, k);} else {return quick_sort(j + 1, r, k - (j - l + 1));}};cout << quick_sort(0, n - 1, k) << endl;
}int main() {int t;t = 1;while (t --) {solve();}return 0;
}
 
2.归并排序
// Problem: 归并排序
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/789/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// Author:lvzihao521
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>using namespace std;
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using pii = pair<i64, i64>;void solve() {int n;cin >> n;vector<int> a(n), t(n);for (int i = 0; i < n; i ++) {cin >> a[i];}function<void(int l, int r)> merge_sort = [&](int l, int r) -> void {if (l >= r) {return ;}int mid = l + r >> 1;merge_sort(l, mid);merge_sort(mid + 1, r);int i = l, j = mid + 1, k = 0;while (i <= mid && j <= r) {if (a[i] <= a[j]) {t[k ++] = a[i ++];} else {t[k ++] = a[j ++];}}while (i <= mid) {t[k ++] = a[i ++];}while (j <= r) {t[k ++] = a[j ++];}for (i = l, k = 0; i <= r; i ++, k ++) {a[i] = t[k];}};merge_sort(0, n - 1);for (int i = 0; i < n; i ++) {cout << a[i] << " \n"[i == n - 1];}
}int main() {int t;t = 1;while (t --) {solve();}return 0;
} 
逆序对个数
// Problem: 逆序对的数量
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/790/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// Author:lvzihao521
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>using namespace std;
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using pii = pair<i64, i64>;void solve() {int n;cin >> n;vector<int> a(n), t(n);for (int i = 0; i < n; i ++) {cin >> a[i];}function<i64(int l, int r)> merge_sort = [&](int l, int r) -> i64 {i64 res = 0;if (l >= r) {return 0;}int mid = l + r >> 1;res += merge_sort(l, mid) + merge_sort(mid + 1, r);int i = l, j = mid + 1, k = 0;while (i <= mid && j <= r) {if (a[i] <= a[j]) {t[k ++] = a[i ++];} else {t[k ++] = a[j ++];res += mid - i + 1;}}while (i <= mid) {t[k ++] = a[i ++];}while (j <= r) {t[k ++] = a[j ++];}for (i = l, k = 0; i <= r; i ++, k ++) {a[i] = t[k];}return res;};i64 res = merge_sort(0, n - 1);cout << res << endl;
}int main() {int t;t = 1;while (t --) {solve();}return 0;
} 
3.二分
二分不是特别简单的题面都是需要写一个check函数的,check函数是二分的一个难点,因题而异,所以我下面的模板是基于check函数写好以后写的
区间左端点
int l = 0, r = 1e9;
while (l < r) {int mid = l + r >> 1;if (check(mid)) r = mid;else l = mid + 1;
}
 
区间右端点
int l = 0, r = 1e9;
while (l < r) {int mid = l + r + 1 >> 1;if (check(mid)) l = mid;else r = mid - 1;
}
 
4.高精度
高精度顾名思义就是一些数字太大了,比如有1000位,无法直接进行运算,但是我们可以通过把这些数字放到数组里,然后一位一位的做运算,相当于在模拟咱们手动列竖式的感觉
1.加法
vector<int> add(vector<int> &a, vector<int> &b) {vector<int> res;int t = 0;for (int i = 0; i < a.size() || i < b.size(); i ++) {if (i < a.size()) {t += a[i];}if (i < b.size()) {t += b[i];}res.emplace_back(t % 10);t /= 10;}if (t) {res.emplace_back(t);}return res;
}
 
2.减法
减法的话,他需要多写一个比较函数,因为咱们只能实现大数减小数,如果是小数减大数的话,通过cmp函数改成大数减小数,并且手动加负号就可以,我在这里只是实现一下这两个函数,
在做完运算后,可能会出现123456 - 123000 = 000456的问题,所以最后我们要去除前导零。
bool cmp(vector<int> &a, vector<int> &b) {if (a.size() != b.size()) {return a.size() > b.size();}for (int i = a.size() - 1; i >= 0; i --) {if (a[i] != b[i]) {return a[i] > b[i];}}return true;
}vector<int> sub(vector<int> &a, vector<int> &b) {vector<int> res;int t = 0;for (int i = 0; i < a.size(); i ++) {t = a[i] - t;if (i < b.size()) {t -= b[i];}res.emplace_back((t + 10) % 10);t = t < 0 ? 1 : 0;}while (res.size() > 1 && res.back() == 0) {res.pop_back();}return res;
}
 
3.乘法
乘法的模板我分为两个,一个高精度乘低精度,一个高精度乘高精度,前一个更常用,要比后一个要熟练掌握
vector<int> mul(vector<int> &a, int b) {vector<int> res;int t = 0;for (int i = 0; i < a.size() || t; i ++) {if (i < a.size()) {t += a[i] * b;}res.emplace_back(t % 10);t /= 10;}while (res.size() > 1 && res.back() == 0) {res.pop_back();}return res;
}
 
vector<int> mul(vector<int> &a, vector<int> &b) {vector<int> res(a.size() + b.size() + 10);for (int i = 0; i < a.size(); i ++) {for (int j = 0; j < b.size(); j ++) {res[i + j] += a[i] * b[j];}}int t = 0;//完成进位的操作for (int i = 0; i < res.size(); i ++) {t += res[i];res[i] = t % 10;t /= 10;}while (res.size() > 1 && res.back() == 0) {res.pop_back();}return res;
}
 
4.除法
由于本人不熟悉除法(我根本没有用过),所以这里我也是复制粘贴来的。原理也不难,可以求得商和余数,一样类比列竖式。
vector<int> div(vector<int> &A, int b, int &r) {vector<int> res;r = 0;for (int i = A.size() - 1; i >= 0; i -- ){r = r * 10 + A[i];res.emplace_back(r / b);r %= b;}reverse(res.begin(), res.end());while (res.size() > 1 && res.back() == 0){res.pop_back();}return res;
}
 
5.前缀和
5.1一维前缀和
这就是给咱们一个数组,然后对他进行一个操作,使得下标为i就是前i项和,这是O(1)的复杂度
vector<int> s(n + 1);
//....
//经过赋值后
for (int i = 1; i <= n; i ++) {s[i] += s[i - 1];
}
//不想改变原数组的话,也可以这样
//vector<int> b(n + 1);
//for (int i = 0; i < n; i ++) {
//    b[i] = b[i - 1] + s[i];
//}
 
5.2二维前缀和
和上面同理s[i][j]就表示长为j,高为i的矩阵的和
vector<vector<int>> s(n + 10, vector<int> (m + 10));
//...
//经过赋值后
for (int i = 1; i <= n; i ++) {for (int j = 1; j <= m; j ++) {s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];}
}
 
6.差分
这可以看成是前缀和的逆运算
它可以做到对一个区间内用一次操作来加减一个数
也有题的类型是找最小操作数,也是要用差分
6.1一维差分
vector<int> s(n + 1);
for (int i = n; i >= 1; i --) {s[i] -= s[i - 1];
}
 
6.2二维差分
vector<vector<int>> s(n + 10, vector<int> (m + 10));
//...
//初始化完成后
function<void(int x1, int y1, int x2, int y2, int r)> insert = [&](int x1, int y1, int x2, int y2, int r) -> void {s[x1][y1] += r;s[x2 + 1][y1] -= r;s[x1][y2 + 1] -= r;s[x2 + 1][y2 + 1] += r;
}
for (int i = 1; i <= n; i ++) {for (int j = 1; j <= n; j ++) {insert(i, j, i, j, s[i][j]);}
}while (q --) {int x1, x2, y1, y2, r;cin >> x1 >> y1 >> x2 >> y2, r;insert(x1, y1, x2, y2, r);
}
//来个前缀和复原
for (int i = 1; i <= n; i ++) {for (int j = 1; j <= m; j ++) {s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];}
}
 
7.双指针
 常用做法
 1.两个指针从头一起走
 2.一个指针从头开始,一个指针从尾开始
8.位运算
8.1左移<<
在二进制表示下把数字同时向左移动,高位越界舍弃,低位补零。
8.2 右移>>
在二进制补码表示下把数字同时向右移动,高位以0补充,低位越界舍弃
8.3 与&
二进制表示下两位同时为1则为1,否则为0
8.4 或|
二进制表示下只要有一位为1则为1,否则为0
8.5 异或^
二进制表示下两个不同就为1,相同就为0
9. 离散化
这种题就是一些数字分布在一个很大的区间里,但是数字的总个数很少,开不了这么大的数组,怎么办呢,我们可以利用set和map来离散化,用set来把所有要用到的下标记录下来,然后用map把这些下标映射成1,2,3,4,5…n,然后把值加上去,这就是离散化。
这种感觉得多做题才会有感觉
10.区间合并
这个其实就相当于是一个操作了,能记住就行,记不住也能现推
先把所有的区间都存到一个vector里,然后,传入其中,里面的ed和seg.first的判断会因题做点小改变。
st和ed的初始值记住是极小值就行,因题有可能也会变
void merge(vector<pii> &segs) {vector<pii> res;int st = -2e9, ed = -2e9;sort(segs.begin(), segs.end());for (auto seg : segs) {if (ed < seg.first) {if (st != -2e9) {res.emplace_back(st, ed);}st = seg.first, ed = seg.second;} else {ed = max(ed, seg.second);}}if (st != -2e9) {res.emplace_back(st, ed);}segs = res;
}
相关文章:
算法阶段总结1
阶段总结 通过今天晚上的这场div2我深刻的意识到,光是会找窍门是远远不够的,你得会基础的建图,dp,高级数据结构,你这样才可以不断的提升自己,不可以一直在一个阶段停留下去,构造题可以刷下去&a…...
前端宝典之七:React性能优化实战精华篇
本文主要讲解实战项目中React性能优化的方法,主要分为三个大的方面:减少不必要的组件更新、组件优化以及tree-shaking,共11个方法 一、减少不必要组件更新 以下是一些可以避免在 React 提交阶段进行不必要重新渲染的方法: 1、使…...
【Dash】feffery_antd_components 简单入门示例
一、简单了解 feffery_antd_components 简称 fac ,是一个基于 Ant Design 的 Dash 第三方组件,由Feffery 老师开源维护的 Python 网页开发组件库,它具有丰富的页面常用交互组件功能,使开发者可以使用纯Python的方式快速构建现代…...
JAVA学习-练习试用Java实现“路径交叉”
问题: 给定一个整数数组 distance 。从 X-Y 平面上的点 (0,0) 开始,先向北移动 distance[0] 米,然后向西移动 distance[1] 米,向南移动 distance[2] 米,向东移动 distance[3] 米,持续移动。也就是说&#…...
element组件封装
1.上传组件 <!--文件上传组件--> <template><div class"upload-file"><el-uploadref"fileUpload"v-if"props.type default":action"baseURL other.adaptationUrl(props.uploadFileUrl)":before-upload"h…...
Mysql (面试篇)
目录 唯一索引比普通索引快吗 MySQL由哪些部分组成,分别用来做什么 MySQL查询缓存有什么弊端,应该什么情况下使用,8.0版本对查询缓存由上面变更 MyISAM和InnoDB的区别有哪些 MySQL怎么恢复半个月前的数据 MySQL事务的隔离级别ÿ…...
【python】深入探讨python中的抽象类,创建、实现方法以及应用实战
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
微前端传值
在微前端架构中,不同子应用之间通过 postMessage 进行通信是一种常见的做法。这种方式允许不同源的窗口之间进行安全的信息交换。 下面是如何使用 postMessage 在微前端环境中发送和接收消息的示例。 步骤 1: 发送消息 假设您有一个主应用(host app&a…...
《学会 SpringBoot · 依赖管理机制》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...
全网行为管理软件有哪些?5款总有一款适合你的企业!
如今企业越来越依赖互联网进行日常运营和业务发展,网络行为管理变得日益重要。 为了确保网络安全、提高员工工作效率、避免敏感信息外泄等问题,企业往往需要借助全网行为管理软件来监控和管理内部网络的使用情况。 本文将为您介绍五款热门的全网行为管理…...
以简单的例子从头开始建spring boot web多模块项目(二)-mybatis简单集成
继续使用以简单的例子从头开始建spring boot web多模块项目(一)中的项目进行mybatis集成。 1、pom.xml文件中,增加相关的依赖包的引入,分别是mybatis-spring-boot-starter、lombok、mysql-connector-java 如下: <d…...
Golang | Leetcode Golang题解之第354题俄罗斯套娃信封问题
题目: 题解: func maxEnvelopes(envelopes [][]int) int {n : len(envelopes)if n 0 {return 0}sort.Slice(envelopes, func(i, j int) bool {a, b : envelopes[i], envelopes[j]return a[0] < b[0] || a[0] b[0] && a[1] > b[1]})f : …...
jmeter中添加ip欺骗
1、首先在本机电脑中通过配置文件创建添加ip的配置文件,先创建一个txt格式的,直接修改文件名以及后缀为ips.bat 2、编辑该ips.bat文件,在文件中输入如下内容,用于快速给本机添加ip地址,(2,1&…...
WPF篇(19)-TabControl控件+TreeView树控件
TabControl控件 TabControl表示包含多个共享相同的空间在屏幕上的项的控件。它也是继承于Selector基类,所以TabControl也只支持单选操作。另外,TabControl的元素只能是TabItem,这个TabItem继承于HeaderedContentControl类,所以Ta…...
appium下载及安装
下载地址:https://github.com/appium/appium-desktop/releases 双击安装就可以...
XSS项目实战
目录 一、项目来源 二、实战操作 EASY 1 2 3 4 5 6 7 8 一、项目来源 XSS Game - Learning XSS Made Simple! | Created by PwnFunction 二、实战操作 EASY 1 1.Easy -1 2.题目要求及源码 Difficulty is Easy.Pop an alert(1337) on sandbox.pwnfunction.com.No …...
SD-WAN降低网络运维难度的关键技术解析
为什么说SD-WAN(软件定义广域网)大大降低了网络运维的复杂性,主要是因为它的智能路径选择、应用识别和链路质量监测这三个核心技术。这几项在SD-WAN中尤为重要的技术,它们共同作用,提升了整体网络性能,为网…...
【算法基础实验】图论-最小生成树-Prim的即时实现
理论知识 Prim算法是一种用于计算加权无向图的最小生成树(MST, Minimum Spanning Tree)的贪心算法。最小生成树是一个连通的无向图的子图,它包含所有的顶点且总权重最小。Prim算法从一个起始顶点开始,不断将权重最小的边加入生成…...
LLama 3 跨各种 GPU 类型的基准测试
2024 年 4 月 18 日,AI 社区对 Llama 3 70B 的发布表示欢迎,这是一款最先进的大型语言模型 (LLM)。该型号是 Llama 系列的下一代产品,支持广泛的用例。该模型 istelf 在广泛的行业平台上表现良好,并提供了新…...
FreeRTOS 快速入门(五)之信号量
目录 一、信号量的特性1、信号量跟队列的对比2、两种信号量的对比 二、信号量1、二值信号量1.1 二值信号量用于同步1.2 二值信号量用于互斥 2、计数信号量 三、信号量函数1、创建2、删除3、give/take 一、信号量的特性 信号量(Semaphore)是一种实现任务…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
