【一】【算法】经典树状数组和并查集,详细解析,初步认识,【模板】树状数组 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; // 树状数组

    // 计算lowbit
    int 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+5
    readd.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位置增加k
            t1.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 { // 定义结构体 node
    int 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,值为 0
    sizee.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) { // 如果操作类型为 1
            if(fx == fy) cout << "Yes" << endl; // 如果 x 和 y 在同一个集合,输出 "Yes"
            else cout << "No" << endl; // 否则输出 "No"
        } else { // 如果操作类型为 0
            unionn(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; // 定义临时变量 tt
        cin >> tt.op >> tt.x >> tt.y; // 输入操作类型和操作数
        readd.push_back(tt); // 将操作存入 readd 向量
    }

    solve(); // 调用 solve 函数处理操作
}

结尾

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Win11下安装VS2022失败的解决办法

前几天我把我的HP Z840的操作系统换成了Win11&#xff0c;在重装VS2022时遇到了麻烦&#xff0c;提示无法安装 Microsoft.VisualStudio.Devenv.Msi。 查看安装日志提示&#xff1a;Could not write value devenv.exe to key \SOFTWARE\Microsoft\Internet Explorer\Main\Featur…

DataWhale - 吃瓜教程学习笔记(二)

学习视频&#xff1a;第3章-一元线性回归_哔哩哔哩_bilibili 西瓜书对应章节&#xff1a; 3.1 - 3.2 一元线性回归 - 最小二乘法 - 极大似然估计 - 梯度 多元函数的一阶导数 - 海塞矩阵 多元函数的二阶导数 - 机器学习三要素

SpringBoot 快速入门(保姆级详细教程)

目录 一、Springboot简介 二、SpringBoot 优点&#xff1a; 三、快速入门 1、新建工程 方式2&#xff1a;使用Spring Initializr创建项目 写在前面&#xff1a; SpringBoot 是 Spring家族中的一个全新框架&#xff0c;用来简化spring程序的创建和开发过程。SpringBoot化繁…

qt+halcon实战

注意建QT工程项目用的是MSVC&#xff0c;如果选成MinGW,则会报错 INCLUDEPATH $$PWD/include INCLUDEPATH $$PWD/include/halconcppLIBS $$PWD/lib/x64-win64/halconcpp.lib LIBS $$PWD/lib/x64-win64/halcon.lib#include "halconcpp/HalconCpp.h" #include &quo…

CompletableFuture 基本用法

一、 CompletableFuture简介 CompletableFuture 是 Java 8 引入的一个功能强大的类&#xff0c;用于异步编程和并发处理。它提供了丰富的 API 来处理异步任务的结果&#xff0c;支持函数式编程风格&#xff0c;并允许通过链式调用组合多个异步操作。 二、CompletableFuture中…

尚品汇-(四)

&#xff08;1&#xff09;商品的基本知识 1.1基本信息—分类 一般情况可以分为两级或者三级。咱们的项目一共分为三级&#xff0c;即一级分类、二级分类、三级分类。 比如&#xff1a;家用电器是一级分类&#xff0c;电视是二级分类&#xff0c;那么超薄电视就是三级分类。…

已解决VirtualMachineError: 虚拟机错误的正确解决方法,亲测有效!!!

已解决VirtualMachineError: 虚拟机错误的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 报错原因 解决思路 解决方法 分析错误日志 优化代码 内存泄漏排查 优化递归调用 调整JVM参数 使用监控工具 增加物理内存或升级硬件…

Jmeter5.X性能测试【完整版】

目录 一、Http基础协议和解析 1、浏览器的B/S架构和C/S架构 &#xff08;1&#xff09;CS架构 &#xff08;2&#xff09;BS架构 &#xff08;3&#xff09;URL理解 2、Http超文本传输协议 &#xff08;1&#xff09;含义 # 协议 # json协议 # xml协议 &#xff08;…

mysql分析常用锁、动态监控、及优化思考

这里写自定义目录标题 1.未提交事物&#xff0c;阻塞DDL&#xff0c;继而阻塞所有同表的后续操作,查看未提交事务的进程2.存着正在进行的线程数据。3.根据processlist表中的id杀掉未释放的线程4.查看正在使用的表5.mysql为什么state会有waiting for handler commit6.什么情况导…

简易智能家居系统

文章目录 摘要一、系统设计要求及总体设计方案1.1 设计要求1.2 总体设计方案 二、终端结点的设计及实现2.1单片机最小系统2.2 LED灯的控制与工作状态的显示2.2.1 硬件设计2.2.2 软件设计 2.3 温度的测量与显示2.4 火灾的监测与报警2.5 串口的显示与控制 三、网络传输与控制3.1 …

人工智能在影像组学与放射组学中的最新进展|顶刊速递·24-06-22

小罗碎碎念 本期文献速递的主题——人工智能在影像组学中的最新进展。 小罗一直以来的观点&#xff0c;是把大问题分模块拆解——既然我们想做多模态&#xff0c;那么就先了解单模态的研究套路&#xff0c;再去研究不同模态提取的特征如何融合&#xff0c;搞科研的过程也是管理…

Flutter Android 调试桥 (adb)

客户端&#xff1a;用于发送命令。客户端在开发计算机上运行。您可以通过发出 adb 命令从命令行终端调用客户端。 守护程序adbd&#xff1a;用于在设备上运行命令。守护程序在每个设备上作为后台进程运行。 服务器&#xff1a;用于管理客户端与守护程序之间的通信。服务器在开…

刷代码随想录有感(113):动态规划——爬楼梯plus

题干&#xff1a; 代码&#xff1a; #include<bits/stdc.h> using namespace std;int main(){int n,m;cin>>n>>m;vector<int>dp(n 1, 0);dp[0] 1;for(int j 0; j < n; j){for(int i 1; i < m; i){if(j > i)dp[j] dp[j - i];}}cout<&…

【吊打面试官系列-Mysql面试题】什么是存储过程?用什么来调用?

大家好&#xff0c;我是锋哥。今天分享关于 【什么是存储过程&#xff1f;用什么来调用&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 什么是存储过程&#xff1f;用什么来调用&#xff1f; 答&#xff1a;存储过程是一个预编译的 SQL 语句&#xff0c;优点是…

PyScada(三)后端应用

PyScada 的后端应用 使用后端 要使用后端&#xff0c;请在浏览器中打开http://127.0.0.1 &#xff08;将 127.0.0.1 替换为 PyScada 服务器的 IP 或主机名&#xff09;&#xff0c;然后使用安装过程 中定义的管理员帐户登录 &#xff08;TODO 链接到创建超级用户文档&#xf…

【数据分享】《中国法律年鉴》1987-2022

而今天要免费分享的数据就是1987-2022年间出版的《中国法律年鉴》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 自1987年起&#xff0c;《中国法律年鉴》作为一部全面记录中国法律发展进程的重要文献&#xff0c;见证了中国法治建设的每…

G7易流赋能化工物流,实现安全、环保与效率的共赢

近日&#xff0c;中国物流与采购联合会在古都西安举办了备受瞩目的第七届化工物流安全环保发展论坛。以"坚守安全底线&#xff0c;追求绿色发展&#xff0c;智能规划化工物流未来"为主题&#xff0c;该论坛吸引了众多政府部门、行业专家和企业代表的参与。G7易流作为…

unity中使用commandbuffer将自定义画面渲染到主相机上

CommandBuffer 保存渲染命令列表&#xff08;例如设置渲染目标或绘制给定网格&#xff09;。您可以指示 Unity 在内置渲染管线中的各个点安排和执行这些命令&#xff0c;因此&#xff0c;您可以自定义和扩展 Unity 的渲染功能。 这句话意味着你可以通过command buffer让相机渲…

数组和链表的区别是什么?

引言&#xff1a;本文旨在深入探讨数组和链表之间的区别&#xff0c;分析它们在不同情境下的优缺点&#xff0c;并探讨如何根据应用需求选择合适的数据结构。通过深入理解数组和链表的内部工作原理和应用场景&#xff0c;读者将能够更好地应用这些知识解决实际问题&#xff0c;…

web中间件漏洞-Jenkins漏洞-弱口令、反弹shell

web中间件漏洞-Jenkins漏洞-弱口令、反弹shell Jenkins弱口令 默认用户一般为jenkins/jenkins 使用admin/admin123登陆成功 Jenkins反弹shell 格式为 println"命令".execute().text 在/tmp目录中生成shell.sh文件&#xff0c;并向其中写入反弹shell的语句 new…