【一】【算法】经典树状数组和并查集,详细解析,初步认识,【模板】树状数组 1,树状数组并查集

【模板】树状数组 1

题目描述

如题,已知一个数列,你需要进行下面两种操作:

  • 将某一个数加上 x x x

  • 求出某区间每一个数的和

输入格式

第一行包含两个正整数 n , m n,m n,m,分别表示该数列数字的个数和操作的总个数。

第二行包含 n n n 个用空格分隔的整数,其中第 i i i 个数字表示数列第 i i i 项的初始值。

接下来 m m m 行每行包含 3 3 3 个整数,表示一个操作,具体如下:

  • 1 x k 含义:将第 x x x 个数加上 k k k

  • 2 x y 含义:输出区间 [ x , y ] [x,y] [x,y] 内每个数的和

输出格式

输出包含若干行整数,即为所有操作 2 2 2 的结果。

样例 #1

样例输入 #1

5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4

样例输出 #1

14
16

提示

【数据范围】

对于 30 % 30\% 30% 的数据, 1 ≤ n ≤ 8 1 \le n \le 8 1n8 1 ≤ m ≤ 10 1\le m \le 10 1m10
对于 70 % 70\% 70% 的数据, 1 ≤ n , m ≤ 1 0 4 1\le n,m \le 10^4 1n,m104
对于 100 % 100\% 100% 的数据, 1 ≤ n , m ≤ 5 × 1 0 5 1\le n,m \le 5\times 10^5 1n,m5×105

数据保证对于任意时刻, a a a 的任意子区间(包括长度为 1 1 1 n n n 的子区间)和均在 [ − 2 31 , 2 31 ) [-2^{31}, 2^{31}) [231,231) 范围内。

样例说明:

故输出结果14、16

树状数组

树状数组(Binary Indexed Tree,简称 BIT)是一种用于高效处理频繁更新和前缀和查询的数据结构。它能够在 O(logn) 时间复杂度内完成更新和查询操作,因此在处理需要频繁动态更新的数据时非常有用。

经典树状数组主要用于解决以下两类问题:
单点更新问题:对数组中的某个元素进行更新(加一个值或改为一个新值)。
前缀和问题:求数组中从第一个元素到某个位置的前缀和。

树状数组的原理

树状数组存储的信息

假设arr数组有九个元素,tree数组同样有九个元素,这九个元素的下标从1开始计算.
在这里插入图片描述
tree数组下标1存储arr数组中下标1累加和.
tree数组下标2存储arr数组中下标1,2累加和.
tree数组下标3存储arr数组中下标3累加和.
tree数组下标4存储arr数组中下标1,2,3,4累加和.
tree数组下标5存储arr数组中下标5累加和.
tree数组下标6存储arr数组中下标5,6累加和.
tree数组下标7存储arr数组中下标7累加和.
tree数组下标8存储arr数组中下标1,2,3,4,5,6,7,8累加和.
tree数组下标9存储arr数组中下标9累加和.

树状数组存储信息的理解

在这里插入图片描述
在右边画出1,2,3,4,5,6,7,8,9.
tree数组下标1存储arr数组下标1的累加和.在右边1下面画一条长度为1的线.
tree数组下标2存储arr数组中下标1,2累加和.在右边2下面画一条长度为1的线,前面线长度为1和自己的长度相同,那么两者合并成长度为2的线.表示1,2累加和.
tree数组下标3存储arr数组中下标3累加和.在右边3下面画一条长度为1的线,前面线的长度为2,和自己的长度不相同,不能合并.
tree数组下标4存储arr数组中下标1,2,3,4累加和.在右边4下面画一条长度为1的线,前面线的长度为1,和自己的长度相同,合并在一起得到长度为2的线,对应34位置,前面线的长度为2,和自己的长度相同,合并在一起得到长度为4的线,表示1,2,3,4累加和.
tree数组下标5存储arr数组中下标5累加和.在右边5下面画一条长度为1的线,前面线的长度是4,和自己不相同,不能合并.
tree数组下标6存储arr数组中下标5,6累加和.在右边6下面画一条长度为1的线,前面线的长度是1,和自己相同,合并成长度为2的线,前面线的长度为4,和自己不相同,不能合并.
tree数组下标7存储arr数组中下标7累加和.在右边7下面画上一条长度为1的线,前面线的长度为2,和自己不相同不能合并.
tree数组下标8存储arr数组中下标1,2,3,4,5,6,7,8累加和.,在右边8下面画一条长度为1的线,前面线的长度为1,和自己相同,合并在一起长度为2,前面线的长度为2,和自己相同,合并在一起长度为4,前面线的长度为4,和自己相同,合并在一起长度为8,表示1,2,3,4,5,6,7,8累加和.
tree数组下标9存储arr数组中下标9累加和.在右边9下面画一条长度为1的线,前面线的长度为8,和自己不相同,不能合并.

lowbit(int i)函数

lowbit(int i){return i&(-i);
}

lowbit 函数在树状数组(Binary Indexed Tree, BIT)中扮演着关键角色,主要用于确定如何在更新和查询操作中跳转节点。lowbit 函数的作用是获取一个数的最低位的1所表示的值。
具体来说,lowbit(x) 返回的是 x 的二进制表示中最低位的1所在的位置所表示的值。在二进制中,最低位的1表示的值是 x & -x。

在二进制中-x是通过对x的二进制按位取反,末尾加一得到.
在这里插入图片描述
对于任意的x,x&(-x)的结果是只保留x在二进制中最低位的1,其余的数全是0.

add(int i,int v) 函数

    void add(int i, int v) {while (i <= n) {tree[i] += v;i += lowbit(i);}}

该函数的意思是将arr数组中i位置的值加上v.
在这里插入图片描述
我们只处理tree数组中的数据,假设我们调用add(5,3),将arr[5]+=3.
那么我们需要将tree数组中下标为5,6,8位置的元素全部加上3.表示这些位置中含有的下标5的值增加3.
在这里插入图片描述
我们研究其二进制数可以发现,数字5的二进制数加上lowbit(5)得到的数是6,数字6的二进制数加上lowbit(6)得到的数是8.

在这里插入图片描述
假设我们再调用add(4,3),将arr[4]+=3.
那么我们需要将tree数组中4,8下标位置的元素全部加上3,表示这些位置中含有的下标4的值增加3.
在这里插入图片描述
我们研究其二进制数可以发现,数字4的二进制数加上lowbit(4)得到的数是8.

实际上对于arr数组中任意的i位置我们增加v,对应tree数组中需要修改的位置是i,i+lowbit(i)=newi,newi+lowbit(newi)…直到越界为止.

sum(int i)函数

    int sum(int i) {int ret = 0;while (i > 0) {ret += tree[i];i -= lowbit(i);}return ret;}

sum 函数在树状数组(Binary Indexed Tree, BIT)中通常用于计算数组的前缀和,即从数组开头到某个位置的元素总和。这个操作在 BIT 中能够以对数时间复杂度 O(logn) 来完成。

在这里插入图片描述
假设我们需要求arr数组中1~6前缀和,对应tree数组中需要得到下标4,6的累加和.
在这里插入图片描述
研究其二进制关系,发现6的二进制数减去lowbit(6)得到的数是4.

在这里插入图片描述
假设我们需要求arr数组中1~7前缀和,对应tree数组中需要得到下标4,6,7累加和.
在这里插入图片描述
研究其二进制数关系发现,7的二进制数减去lowbit(7)得到的数是6.
6的二进制数减去lowbit(6)得到的数是4.

实际上我们需要求arr数组中1~x的前缀和,对应tree数组中需要累加的下标位置分别是,x,x-lowbit(x)=newx,newx-lowbit(newx)…直到遇到下标0为止.

range(int l,int r)

    int range(int l, int r) {return sum(r) - sum(l - 1);}

range函数计算arr数组中区间和,区间和用前缀和加工得到.

完整代码

#include<bits/stdc++.h> // 引入标准库
using namespace std;#define int long long // 定义长整型为int
#define endl '\n' // 定义换行符int n, m; // n表示数列长度,m表示操作的总个数
vector<int> arr; // 存储数列的数组
vector<int> diff; // 存储差分数组
struct node {int op, x, y, k; // op表示操作类型,x和y表示操作的参数,k表示增加的值
};
vector<node> readd; // 存储所有操作的数组class Tree { // 树状数组类
public:vector<int> tree; // 树状数组// 计算lowbitint lowbit(int i) {return i & -i;}// 在树状数组中增加值void add(int i, int k) {while (i <= n) {tree[i] += k;i += lowbit(i);}}// 计算前缀和int sum(int i) {int ret = 0;while (i > 0) {ret += tree[i];i -= lowbit(i);}return ret;}// 计算区间和int range(int l, int r) {return sum(r) - sum(l - 1);}// 构造函数,用于初始化树状数组Tree(vector<int> arr) {tree.assign(arr.size(), 0); // 初始化树状数组for (int i = 1; i < arr.size(); i++) {add(i, arr[i]); // 初始化时将数组中的值加入树状数组}}Tree() {} // 默认构造函数
};Tree t1; // 定义树状数组对象void init() { // 初始化函数cin >> n >> m; // 读取数列长度和操作个数arr.assign(n + 5, 0); // 初始化数组,大小为n+5readd.clear(); // 清空操作数组for (int i = 1; i <= n; i++) {cin >> arr[i]; // 读取数列初始值}for (int i = 1; i <= m; i++) {int op = 0, x = 0, y = 0, k = 0;cin >> op; // 读取操作类型if (op == 1) {cin >> x >> y >> k; // 读取区间增加操作的参数} else {cin >> x; // 读取查询操作的参数}readd.push_back({ op, x, y, k }); // 将操作存储到操作数组中}
}void solve() {diff.assign(arr.size(), 0); // 初始化差分数组for (int i = 1; i < arr.size(); i++) {diff[i] = arr[i] - arr[i - 1]; // 计算差分数组}t1 = Tree(diff); // 初始化树状数组for (auto& xx : readd) { // 遍历所有操作int op = xx.op, x = xx.x, y = xx.y, k = xx.k;if (op == 1) { // 如果是增加操作t1.add(x, k); // 在x位置增加kt1.add(y + 1, -k); // 在y+1位置减少k} else { // 如果是查询操作cout << t1.sum(x) << endl; // 输出第x个数的值}}
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 提高输入输出效率init(); // 初始化solve(); // 处理所有操作
}

并查集

并查集模板
描述
给定一个没有重复值的整形数组arr,初始时认为arr中每一个数各自都是一个单独的集合。请设计一种叫UnionFind的结构,并提供以下两个操作。
boolean isSameSet(int a, int b): 查询a和b这两个数是否属于一个集合
void union(int a,int b): 把a所在的集合与b所在的集合合并在一起,原本两个集合各自的元素以后都算作同一个集合
[要求]
如果调用isSameSet和union的总次数逼近或超过O(N),请做到单次调用isSameSet或union方法的平均时间复杂度为O(1)
输入描述: 第一行两个整数N, M。分别表示数组大小、操作次数 接下来M行,每行有一个整数opt
若opt = 1,后面有两个数x,y,表示查询(x, y)这两个数是否属于同一个集合
若opt = 2,后面有两个数x, y,表示把x, y所在的集合合并在一起 输出描述:
对于每个opt = 1的操作,若为真则输出"Yes",否则输出"No"
示例1 输入: 4 5 1 1 2 2 2 3 2 1 3 1 1
1 1 2 3 复制
输出: No Yes Yes 复制
说明: 每次2操作后的集合为 ({1}, {2}, {3}, {4}) ({1}, {2, 3}, {4}) ({1, 2, 3}, {4})
备注: 1 \leqslant N, M \leqslant
10^61⩽N,M⩽10 6 保证1 \leqslant x, y \leqslant N保证1⩽x,y⩽N

并查集(Disjoint Set Union, DSU)是一种用于处理不相交集合的数据结构,支持高效的合并(union)和查找(find)操作。find 函数在并查集中用于查找元素所属的集合代表(即根节点)。为了提高查找效率,find 函数通常结合路径压缩(path compression)技术使用。

并查集原理

father数组存储的信息

在这里插入图片描述
一开始元素1,2,3,4都是自己和自己一个集合.
index下标表示的是每一个元素,father元素值表示的元素的父亲节点元素.
一开始所有的元素的父亲节点都是自己.

代表节点

如果一个元素的父亲节点是自己,那么这个节点就是代表节点,也叫做代表元素,此时这个元素表示的就是一个集合.

find(int i)函数

int findd(int i) { // 查找操作,带路径压缩if (father[i] != i) father[i] = findd(father[i]); // 如果 i 不是自己的父节点,递归查找父节点return father[i]; // 返回父节点
}

find 函数用于找到某个元素所属集合的根节点.

在这里插入图片描述
find(4),判断4是不是代表元素,4指向的不是自己,不是代表元素,那么就往上面走,4指向3,判断3是不是代表元素,3指向的不是自己,不是代表元素,继续往上走,3指向2,判断2是不是代表元素,2指向的不是自己,不是代表元素,继续往上走,2指向1,判断1是不是代表元素,1是代表元素,所以4所在的集合是1所在集合的集合.

在这里插入图片描述
find(2),判断2是不是代表元素,2指向的不是自己,不是代表元素,往上走,2指向的是1,判断1是不是代表元素,1指向的是自己,1是代表元素.所以2元素所在的集合是1元素所在集合的集合.

以此类推,find(4)=3,find(3)=3.

find函数的扁平化处理

在并查集(Disjoint Set Union, DSU)中,find 函数的路径压缩(或称扁平化处理)是一种优化技术,旨在加速后续的查找操作。路径压缩通过在查找过程中将访问路径上的所有节点直接连接到根节点,减少树的高度,从而提高了查找和合并操作的效率。

在这里插入图片描述
当我们find(1)操作之后,得到的信息是1的代表元素是4,并且在这次寻找中走过的路径是1,2,3,那么将1,2,3全部直接指向代表元素4.

union(int a,int b)函数

void unionn(int x, int y) { // 合并操作int fx = findd(x), fy = findd(y); // 查找 x 和 y 的根节点father[fx] = father[fy]; // 将 x 的根节点指向 y 的根节点
}

在并查集(Disjoint Set Union, DSU)中,union 函数用于将两个不同的集合合并为一个集合。union 函数通常结合 find 函数使用,以确保两个集合的代表(即根节点)被正确地连接在一起。

在这里插入图片描述
合并a,b元素,将两者归为同一集合,先查找a元素所在集合(代表元素)A,再查找b元素所在集合(代表元素)B,然后修改A指向B或者B指向A.
在这里插入图片描述
合并1,2元素.
1元素所在集合为1,2元素所在集合为2,1指向2或者2指向1.

在这里插入图片描述
合并3,4元素.
查找3元素的代表元素,代表元素是3,查找4元素的代表元素,代表元素是4,3指向4.或者4指向3.

合并2,3元素.
查找2元素的代表元素,代表元素是2,查找3元素的代表元素,代表元素是4,2指向4.或者4指向2.

完整代码

#define debug // 定义调试宏
#ifdef debug // 如果定义了调试宏
#define o(x) #x<<"="<<(x)<<" " // 定义调试输出宏,输出变量名和值
#define bug(code) do{cout<<"L"<<__LINE__<<":";code;<<endl;}while(0) // 定义调试宏,在行号前输出调试信息
#else 
#define bug(code) do{}while(0) // 如果未定义调试宏,则定义空宏
#endif#include<bits/stdc++.h> // 引入所有标准库
using namespace std;#define int long long // 定义 int 为 long long
#define endl '\n' // 定义 endl 为换行符
#define _(i,a,b) for(int i=a;i<=b;i++) // 定义正向循环宏
#define _9(i,a,b) for(int i=a;i>=b;i--) // 定义反向循环宏int n, m; // 定义全局变量 n 和 m
struct node { // 定义结构体 nodeint op, x, y; // 包含三个整数成员 op, x 和 y
};
vector<node> readd; // 定义存储 node 的向量 readd
vector<int> father; // 定义存储父节点的向量 father
vector<int> sizee; // 定义存储集合大小的向量 sizee/*
find递归函数,含义是返回i元素所在集合的代表元素下标.
内部逻辑保证father[i]的维护.
如果father[i]=i是代表元素不需要维护直接返回father[i].
如果father[i]!=i说明不是代表元素,需要维护father[i]
走一步,当前节点的代表元素下标=findd(father[i]).
*/
int findd(int i) { // 查找操作,带路径压缩if(father[i] != i) father[i] = findd(father[i]); // 如果 i 不是自己的父节点,递归查找父节点return father[i]; // 返回父节点
}
/*
合并操作,维护sizee和father
father[fx]=father[fy]
代表元素是fy,fx再也用不到了.所以需要维护fy代表元素的信息,即sizee信息.
*/
void unionn(int x, int y) { // 合并操作int fx = findd(x), fy = findd(y); // 查找 x 和 y 的根节点if(fx != fy) sizee[fy] += sizee[fx]; // 如果根节点不同,合并集合,更新大小father[fx] = father[fy]; // 将 x 的根节点指向 y 的根节点
}void solve() {father.assign(n + 5, 0); // 初始化 father 向量,大小为 n+5,值为 0sizee.assign(n + 5, 1); // 初始化 sizee 向量,大小为 n+5,值为 1_(i, 1, n) father[i] = i; // 初始化每个节点的父节点为自己for(auto& xx : readd) { // 遍历所有操作int op = xx.op, x = xx.x, y = xx.y, fx = findd(x), fy = findd(y); // 获取操作类型和操作数,并查找根节点if(op == 1) { // 如果操作类型为 1if(fx == fy) cout << "Yes" << endl; // 如果 x 和 y 在同一个集合,输出 "Yes"else cout << "No" << endl; // 否则输出 "No"} else { // 如果操作类型为 0unionn(x, y); // 合并 x 和 y 所在的集合}}
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 快速输入输出cin >> n >> m; // 输入 n 和 m_(i, 1, m) { // 循环 m 次node tt; // 定义临时变量 ttcin >> tt.op >> tt.x >> tt.y; // 输入操作类型和操作数readd.push_back(tt); // 将操作存入 readd 向量}solve(); // 调用 solve 函数处理操作
}

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/32300.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java: Annotation processing is not supported for module cycles.

java: Annotation processing is not supported for module cycles. 查了半天是造成了循环依赖 解决步骤 1.打开project structure 2.找到循环依赖的两个或多个模块&#xff0c;在dependencies中找到对应的模块并删除 仅记录我遇到这个问题的解决方法&#xff0c;并不适合所…

七层和四层的区别

OSI七层模型的结构如下&#xff1a; 物理层&#xff08;Physical Layer&#xff09;&#xff1a;负责传输原始比特流&#xff0c;实现数据在物理媒介上的传输&#xff1b; 数据链路层&#xff08;Data Link Layer&#xff09;&#xff1a;负责在相邻节点之间传输数据帧&#…

Git简单使用和理解

workspace: 本地的工作目录。 index/stage&#xff1a;暂存区域&#xff0c;临时保存本地改动。 local repository: 本地仓库&#xff0c;只想最后一次提交HEAD。 remote repository&#xff1a;远程仓库。 对于Git,首先应该明白第一git是一种分布式版本控制系统&#xff0c;最…

后仿真中 module path polarity 问题

目录 一 未知极性 二 正极性 三 负极性 不知道大家有没有遇到这个问题:什么?我们知道的module path delay 指的是定义在specify...endspecify block 中的语句,指示输入-输出的延迟信息。 这里的module path 竟然还有极性问题,今天,来学习一下。 模块路径的极性是一…

用RNN构建人名分类器

目录 项目综述1.导入必备的工具包2.处理数据&#xff0c;满足训练要求2.1 统计常用的字符2.2 进行规范化处理,去除重音符号2.3 将文件读取到内存中2.4 构建人名国家和具体人名的对应关系2.5 one-hot编码 3.构建RNN模型3.1 构建传统RNN模型3.2 构建传统LSTM模型3.3 构建传统GRU模…

永久免费设备日志采集工具

免费试用下载: Gitee下载 最新版本 优势: A. 开箱即用. 解压直接运行.不需额外安装. B. 批管理设备. 设备配置均在后台管理. C. 无人值守 客户端自启动,自更新. D. 稳定安全. 架构简单,内存占用小,通过授权访问.

openeuler一个服务异常占用cpu的排查过程

1 环境 硬件环境&#xff1a;LS1046A arm64 系统环境&#xff1a;openEuler release 22.03 (LTS-SP1) Linux kernel 4.19.26 2 问题说明 我的硬件平台需要适配一下 openEuler release 22.03 (LTS-SP1) 但是目前只能使用原来硬件平台的内核&#xff0c;在适配的过程中…

LLM大语言模型应用方案之RAG检索增强生成的实现步骤。

0.我理解的RAG 什么是RAG&#xff1f; RAG的全称是“检索增强生成模型”&#xff08;Retrieval-Augmented Generation&#xff09;。这是一种特别聪明的大语言模型。 RAG是怎么工作的呢&#xff1f; 1.检索&#xff1a;当你问RAG一个问题时&#xff0c;它会先去“图书…

aardio - 【库】lock 跨进程读写锁

import win.ui; /*DSG{{*/ var winform win.form(text"aardio form";right272;bottom203;topmost1) winform.add( button{cls"button";text"无锁演示";left27;top132;right120;bottom184;z2}; button2{cls"button";text"有锁演示…

Redis的实战常用一、验证码登录(解决session共享问题)(思路、意识)

一、基于session实现登录功能 第一步&#xff1a;发送验证码&#xff1a; 用户在提交手机号后&#xff0c;会校验手机号是否合法&#xff1a; 如果不合法&#xff0c;则要求用户重新输入手机号如果手机号合法&#xff0c;后台此时生成对应的验证码&#xff0c;同时将验证码进行…

前端路线指导(4):前端春招秋招经验分享

春招/秋招经验分享(前端) 哈喽大家好&#xff0c;我是小粉&#xff0c;双一流本科&#xff0c;自学前端一年&#xff0c;收获腾讯&#xff0c;字节等多家大厂offer&#xff0c;一半以上ssp~ 今天给大家分享一下我的春招&#xff08;暑期实习&#xff09;、秋招经历&#xff0c;…

【Gradio】如何设置 Gradio 数据框的样式

简介 数据可视化是数据分析和机器学习的关键方面。Gradio DataFrame 组件是一种流行的方式&#xff0c;在网络应用程序中显示表格数据&#xff08;特别是以 pandas DataFrame 对象的形式&#xff09;。 本文将探讨 Gradio 的最新增强功能&#xff0c;这些功能允许用户整合 pand…

Spring的启动扩展点机制详解

在Java的世界中&#xff0c;我们知道Spring是当下最主流的开发框架&#xff0c;没有之一。而在使用Dubbo、Mybatis等开源框架时&#xff0c;我们发现可以采用和Spring完全一样的使用方式来使用它们。 可能你在平时的使用过程中并没有意识到这一点&#xff0c;但仔细想一想&…

解决js打开新页面百度网盘显示不存在方法:啊哦,你所访问的页面不存在了。

用js打开新页面open或window.location.href打开百度网盘后都显示&#xff1a;啊哦&#xff0c;你所访问的页面不存在了。 window.open(baidu_url); window.location.href baidu_url;在浏览器上&#xff0c;回车后网盘资源是可以打开的&#xff0c;刷新也是打开的。这是很奇怪…

深入分析并可视化城市轨道数据

介绍 中国城市化进程加速中&#xff0c;城市轨道交通的迅速扩张成为提升城市运行效率和居民生活品质的关键。这一网络从少数大城市延伸至众多大中型城市&#xff0c;映射了经济飞跃和城市管理现代化。深入分析并可视化城市轨道数据&#xff0c;对于揭示网络特性、评估效率、理…

进程、线程的区别

进程、线程的关系 开工厂生产手机&#xff0c;制作一条生产线&#xff0c;这个生产线上有很多的器件以及材料。一条生产线就是一个进程。 只有生产线是不够的&#xff0c;使用找五个工人来进行生产&#xff0c;这个工人能够利用这些材料最终一步步的将手机做出来&#xff0c;这…

Ansible 自动化运维实践

随着 IT 基础设施的复杂性不断增加&#xff0c;手动运维已无法满足现代企业对高效、可靠的 IT 运维需求。Ansible 作为一款开源的自动化运维工具&#xff0c;通过简洁易用的 YAML 语法和无代理&#xff08;agentless&#xff09;架构&#xff0c;极大简化了系统配置管理、应用部…

LuxTrust、契约锁联合启动中欧两地跨境电子签服务

6月18日&#xff0c;欧洲领先的数字身份和电子签名厂商-LuxTrust、全球领先的数字化技术和服务的提供商-浩鲸科技一行莅临契约锁上海总部&#xff0c;并于当日下午联合举行“跨境签战略合作”现场签约仪式。 三方将以此次合作为契机&#xff0c;发挥各自领域专业优势&#xff…

DS知识点总结--线性表定义及顺序表示

数据结构知识点汇总(考研C版) 文章目录 数据结构知识点汇总(考研C版)二、线性表2.1 线性表的定义和操作2.1.1 线性表的定义2.1.2 线性表的基本操作 2.2 线性表的顺序表示2.2.1 顺序表的定义2.2.2 顺序表上的基本操作的实现 二、线性表 2.1 线性表的定义和操作 2.1.1 线性表的…

区块链会议投稿资讯CCF A--WINE 2024 截止7.15 附录用率 附录用的区块链文章

Conference&#xff1a;The Conference on Web and Internet Economics (WINE) CCF level&#xff1a;CCF A Categories&#xff1a;Cross-cutting/comprehensive/emerging Year&#xff1a;2024 Conference time&#xff1a; December 2-5, 2024 录用率&#xff1a; sele…