单调栈 单调队列 专题

news2024/9/23 13:16:14

文章目录

      • 一、单调栈
        • 1、问题模型
        • 2、实现过程:
        • 3、代码实现
        • 4、规律总结
        • 5、题目练习
      • 二、单调队列
        • 1、问题模型
        • 2、实现过程:
        • 3、代码实现
        • 4、规律总结
        • 5、题目练习
      • 三、总结


一、单调栈

1、问题模型

主要解决一类问题: O ( n ) O(n) O(n) 求数列中每个元素左边/右边第一个大于/小于它的数。

例如,给定一个长度为 N N N 的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 − 1 −1 1

1 ≤ N ≤ 1 0 5 1≤N≤10^5 1N105
1 ≤ 数列中元素 ≤ 1 0 9 1≤数列中元素≤10^9 1数列中元素109

模板题

2、实现过程:

假设现在要求数列中每个数左边第一个比它小的数。

按照朴素做法,对于每个位置都往前遍历,直到找到一个比他小的数停止。
如果数列类似于 5 4 3 2 1,那么这种思路的复杂度就是 O ( n 2 ) O(n^2) O(n2),复杂度很高。

有没有什么办法优化呢?

现在有一个数列 { 2 , 7 , 9 , 5 , 8 , 6 , 3 , . . . } \{2, 7, 9, 5, 8, 6, 3, ...\} {2,7,9,5,8,6,3,...}
前面几个数为 {2, 7, 9}:

  • 后面来一个 5,那么对于数列中后面再来的所有数来说,要找到左边第一个比他们小的数,有 5 在就没 7, 9 什么事了:如果是比 5 大的数,那么找到 5 就停了;如果是比 5 小的数,7, 9 也没什么用。7, 9 两个数对后面再来的数没有价值。然后 5 继续往左找到 2,该数是左边第一个小于它的数,找到了,停止。
    数列中对后面来的数有价值的有 { 2 , 5 } \{2, 5\} {2,5}

  • 接着来了 8,往前找第一个比它小的数,第一个找的数 5 正好比它小,停止。
    数列中对后面来的数有价值的有 { 2 , 5 , 8 } \{2, 5, 8\} {2,5,8}

  • 接着来了 6,往前找第一个比它小的数,发现前面的 8 大于 6,那么数列中后面再来的数就只会参考 6,而数 8 对后面再来的数没有价值。继续往左找到 5 比 6 小,找到了,停止。
    数列中对后面来的数有价值的有 { 2 , 5 , 6 } \{2, 5, 6\} {2,5,6}

  • 接着来了 3,往前找第一个比它小的数,发现前面的 6 大于 3,那么数列中后面再来的数就只会参考 3,而数 6 对后面再来的数没有价值。继续往左找到 5 大于 3,同样 5 对后面再来的数没有价值。继续往左找到 2 比 3 小,找到了,停止。
    数列中对后面来的数有价值的有 { 2 , 3 } \{2, 3\} {2,3}

总结操作规律:
当数列后面一个数 x 来了之后,会往前遍历有价值的数,将比 x 大的数都删掉,没删掉的第一个数就是左边第一个比它小的数;如果删完之后没有数了,说明没有比 x 小的数。

按照这种寻找方式,发现每个数都会找到左边第一个比它小的数,满足了问题要求。
同时发现:
来的每个数要么 O(1) 直接找到前一个数是比他小的数,要么O(n)遍历的时候把前面没有价值的数删掉,为后面再来的数省下时间。
每个数最多会被遍历删掉 1 次,那么整个数列最多会被遍历 1 次,时间复杂度 O ( n ) O(n) O(n)

这种查询方式把原来 O ( n 2 ) O(n^2) O(n2) 的时间复杂度降为了 O ( n ) O(n) O(n)

再次观察操作规律和数列中有价值的数发现:

  • 数列中有价值的数始终是单调递增的;
  • 每次数列中来一个数之后,都是从后往前将有价值数列中的元素依次取出判断,类似栈操作。

所以完全可以把数列中有价值的元素用栈来存储,形成了一个单调递增的栈,叫做单调栈。

3、代码实现

将上述操作规律转化为代码就为:

stack<int> stk; //利用STL中的stack实现栈
for(int i=1;i<=n;i++) //从前往后遍历所有位置
{
	int x; cin >> x; //读入当前元素
	
	while(stk.size() && stk.top() >= x) stk.pop(); //把栈顶所有大于等于当前值的元素弹出,其对后面再来的数没有价值
	
	if(!stk.size()) cout << -1 << ' '; //如果栈空了,说明左边没有比x小的元素,输出-1
	else cout << stk.top() << ' '; //否则栈顶元素即为第一个比x小的元素,将其输出
	
	stk.push(x); //将当前元素入栈
}

整体代码:

#include<bits/stdc++.h>
using namespace std;

const int N = 200010;
int T, n, m;
int a[N];

signed main(){
	cin >> n;
	
	stack<int> stk;
	for(int i=1;i<=n;i++)
	{
		int x; cin >> x;
		
		while(stk.size() && stk.top() >= x) stk.pop();
		
		if(!stk.size()) cout << -1 << ' ';
		else cout << stk.top() << ' ';
		
		stk.push(x);
	}
	return 0;
}

4、规律总结

上述操作通过 维护单调递增栈,求出了数列中每个数左边第一个比它的数
同理可以 维护单调递减栈,求出数列中每个数左边第一个比它的数

将枚举顺序转换,从后往前枚举,便能求出数列中每个数右边第一个比它小/大的数。

5、题目练习

练习1:发射站
题意:
一共 n 个发射站排成一行,每个发射站有高度 H i H_i Hi,能够向左右两边发射能量值为 V i V_i Vi 的能量(最两端的向中间一端)。
每个发射站发出的能量只被两边最近的且比它高的发射站接收。
求出每个发射站接收到的能量值。

1 ≤ N ≤ 1 0 6 , 1≤N≤10^6 , 1N106,
1 ≤ H i ≤ 2 × 1 0 9 , 1≤H_i≤2×10^9, 1Hi2×109,
1 ≤ V i ≤ 10000 1≤V_i≤10000 1Vi10000

思路
每个发射站发出的能量只被两边最近的且比它高的发射站接收,也就是分别求出每个位置左右两边第一个比高度大的位置,将其能量值累加。

Code

#include<iostream>
#include<queue>
#include<stack>
using namespace std;

const int N=1000010;
int n,m;
struct Node{
	int h,val,sum;
}a[N];
int que[N];

int main(){
	cin>>n;
	for(int i=1;i<=n;i++) scanf("%d%d",&a[i].h,&a[i].val);
	
	stack<int> stk;
	for(int i=1;i<=n;i++)
	{
		while(stk.size()&&a[stk.top()].h<=a[i].h) stk.pop();
		
		if(stk.size()) a[stk.top()].sum+=a[i].val;
		stk.push(i);
	}
	
	while(stk.size()) stk.pop();
	
	for(int i=n;i>=1;i--)
	{
		while(stk.size()&&a[stk.top()].h<=a[i].h) stk.pop();
		
		if(stk.size()) a[stk.top()].sum+=a[i].val;
		stk.push(i);
	}
	
	int ans=0;
	for(int i=1;i<=n;i++) ans=max(ans,a[i].sum);
	cout<<ans;
	return 0;

	/* 数组模拟栈实现,耗时更低
	int x=0;
	for(int i=1;i<=n;i++)
	{
		while(x>0&&a[que[x]].h<=a[i].h) x--;
		
		if(x) a[que[x]].sum+=a[i].val;
		que[++x]=i;
	}
	
	x=0;
	for(int i=n;i>=1;i--)
	{
		while(x>0&&a[que[x]].h<=a[i].h) x--;
		
		if(x) a[que[x]].sum+=a[i].val;
		que[++x]=i;
	}
	*/
}

练习2:直方图中最大的矩形
题意
给定 n 个矩形,每个矩形具有相等的宽度,但可以具有不同的高度。
在这里插入图片描述

计算在公共基线处对齐的矩形中能够拼成的最大矩形面积。(此矩形须在公共基线处对齐)

1 ≤ n ≤ 1 0 5 , 1≤n≤10^5, 1n105,
0 ≤ h i ≤ 1 0 9 0≤h_i≤10^9 0hi109

思路
这道题乍一看没有思路,这时就需要仔细观察,观察拼成的矩形特征。

发现能够拼成的矩形的高度一定是所有矩形高度中的一种。

不好直接求出形成的最大矩形,那么就直接暴力枚举所有矩形,就让当前矩形的高度作为拼成的矩形高度
为了让该矩形的面积尽可能大,那么左右两边就要尽可能延伸,最多延伸到哪呢?
往左最多延伸到左边第一个比枚举位置高度小的位置的后一个位置,往右最多延伸到右边第一个比枚举高度小的位置的前一个位置。

用单调栈分别将两个位置求出,然后计算出以当前位置矩形的高度作为拼接矩形高度的最大矩形面积。

取所有位置的求出最大矩形面积的最大值即可。

Code

#include<bits/stdc++.h>
using namespace std;

const int N = 100010;
int n, m;
int a[N], l[N], r[N];

int main(){
	while(cin >> n && n)
	{
		for(int i=1;i<=n;i++) cin >> a[i];
		for(int i=1;i<=n;i++) l[i] = r[i] = 0;
		
		stack<int> stk;
		for(int i=1;i<=n;i++)
		{
			while(stk.size() && a[stk.top()] >= a[i]) stk.pop();
			
			if(stk.size()) l[i] = stk.top();
			stk.push(i);
		}
		while(stk.size()) stk.pop();
		for(int i=n;i>=1;i--)
		{
			while(stk.size() && a[stk.top()] >= a[i]) stk.pop();
			
			if(stk.size()) r[i] = stk.top();
			stk.push(i);
		}
		
		long long maxa = 0;
		for(int i=1;i<=n;i++)
		{
			int L = l[i], R = r[i];
			
			L ++;
			if(!R) R = n;
			else R --;
			
			maxa = max(maxa, (long long)(R - L + 1) * a[i]); //注意开longlong
		}
		cout << maxa << endl;
	}
	return 0;
}

课后练习1:仰视奶牛
课后练习2:找山坡(+思维)
课后练习3:城市游戏(练习2变式,+思维、前缀和)


二、单调队列

1、问题模型

主要解决一类问题: O ( n ) O(n) O(n) 求数列的一个移动区间中元素的最大值/最小值。

例如,给定长度为 n n n 的数组 和 定值 k k k
现有一区间长度为 k,分别求出当区间右端位于 k k k n n n 每个位置时,区间中元素的最大值和最小值。

n ≤ 1 0 6 n≤10^6 n106

模板题

2、实现过程:

朴素做法,每次都遍历整个区间,最坏情况下时间复杂度为 O ( n 2 ) O(n^2) O(n2)
而采用单调队列的思路可以将时间复杂度降为 O ( n ) O(n) O(n)

其实,在上述单调栈的实现过程中,就可以发现:
对于求每个元素左边第一个比它小的元素,维护的单调递增栈而言,每次加入一个元素之后,当前数列中元素的最小值就存放在栈底,栈底元素就是当前数列中元素的最小值
(对于这种现象也不难解释,每次加入一个元素的时候,这个元素都会依次把比其小的栈顶元素弹出,当数列最小值加入的时候,会把栈中所有元素弹出,那么最小值就压到栈底了)

如果我们在这个栈中只存储题目中所描述的长度为 k 的区间中的元素,那么我们把区间中所有数依次加到栈中,维护单调递增栈,就可以直接得到区间最小值了。

在区间向右移动一个位置的过程中,移出了区间最左边的一个位置,区间最右边加进来一个位置。
如果区间最左边移出的元素在维护的单调栈中的话,需要把该元素从栈中删去,然后根据新加的位置元素更新单调递增栈,将其加到栈中即可。栈底元素就是该区间的最小值。
区间每次往后移动一个位置,每次往栈中加入一个元素,当移动完整个数列时,数列中的每个数在栈中最多被遍历删除 1 次,那么就成功将时间复杂度降为 O(n)。

但中间的 如果区间最左边移出的元素在维护的单调栈中的话,需要把该元素从栈中删去 这个过程如何实现呢?
因为是从左往右依次把所有位置入栈来的维护单调递增栈,那么如果区间最左边的元素还在栈中的话,就一定是栈底元素,也就是之前区间的最小值。如果要把这个元素删掉,只需要从栈底取出一个元素删除。

在栈中如何能够从栈底取元素呢?
栈是没有办法从栈底取出元素的,为了实现这个操作只好把栈改为队列,把之前放到栈中的所有元素改为放到队列中,仿照维护单调递增栈的方式维护单调递增队列。

如果区间最左边的元素还在栈中的话,需要把该元素从栈中删去。

那么 如何判断区间最左边移出的元素在不在栈中呢?
只需要看栈底元素,即队列中队头元素 的位置是不是区间最左边移出的位置。
但是此时队列中都是存的元素,元素可能会有重复,如何能够知道队头元素的位置呢?

我们需要在队列中存储元素的位置,而不是元素本身!
(知道位置 i 可以得到元素本身 a[i],但是知道元素的值 x 却不能得到元素的位置。所以为了判断队头元素是不是区间最左边移出的元素,我们干脆在队列中存储元素位置)

分析到这里,整个实现过程就简洁明了了:
把区间中的元素位置依次加入到单调队列中,通过位置得到元素来维护单调递增队列。

在区间移动时:

  • 1、首先判断单调队列队头位置是否是区间最左端移出的位置,如果是,将其弹出;
  • 2、然后根据将新加入的位置更新单调递增队列;
  • 3、将新加入的位置放到队列中。

3、代码实现

根据上述实现过程,转化为对应代码:

//求滑动窗口区间最小值
deque<int> que;
for(int i=1;i<=n;i++)
{
	cin >> a[i];
	if(que.size() && que.front() <= i - m) que.pop_front(); //1、首先判断单调队列队头位置是否是区间最左端移出的位置,如果是,将其弹出;
	while(que.size() && a[que.back()] >= a[i]) que.pop_back(); //2、然后根据将新加入的位置更新单调递增队列;
	
	que.push_back(i); //3、将新加入的位置放到队列中。
	if(i >= m) mina[i] = a[que.front()]; //该单调队列中,队头元素就是区间最小值所在位置
}

完整代码:

#include<bits/stdc++.h>
using namespace std;

const int N = 1000010;
int T, n, m;
int a[N];
int maxa[N], mina[N];

signed main(){
	cin >> n >> m;
	
	deque<int> que;
	
	//求移动区间元素最小值
	for(int i=1;i<=n;i++) 
	{
		if(que.size() && que.front() <= i - m) que.pop_front();
		while(que.size() && a[que.back()] >= a[i]) que.pop_back();
		
		que.push_back(i);
		if(i >= m) mina[i] = a[que.front()];
	}
	
	for(int i=m;i<=n;i++) cout << mina[i] << " ";
	
	return 0;
}

同样可以手写队列:

#include<bits/stdc++.h>
using namespace std;

const int N = 1000010, mod = 1e9+7;
int T, n, m;
int a[N];
int maxa[N], mina[N];
int q[N];

signed main(){
	cin >> n >> m;

	//求移动区间元素最小值
	int st = 0, ed = -1;
	for(int i=1;i<=n;i++)
	{
		if(ed >= st && q[st] <= i - m) st ++;
		while(ed >= st && a[q[ed]] <= a[i]) ed --;
		
		q[++ed] = i;
		if(i >= m) maxa[i] = a[q[st]];
	}
	
	for(int i=m;i<=n;i++) cout << mina[i] << " ";
	
	return 0;
}

4、规律总结

因为实现原理和单调栈一样,所以规律也类似:

  • 求区间最小值,维护单调递增栈;
  • 求区间最大值,维护单调递减栈。

5、题目练习

练习1:最大子序和
题意
给定长度为 n n n 的整数序列,从中找出一段长度不超过 m m m 的连续子序列,使该子序列中元素和最大。
(子序列的长度至少是 1)

1 ≤ n , m ≤ 3 ∗ 1 0 5 1≤n,m≤3*10^5 1n,m3105

思路
一般涉及到连续子序列(子串)问题,都会用到前缀和。
就像之前见过的一道求最大子段和的题目。
那道题是求长度 至少 为 m 的最大连续子序列,而这道题是求长度 不超过 m 的最大连续子序列。

把这两道题放在一起说。
实现思路相同,都是枚举所有位置,把当前位置作为所选子串的末位置,找到前面最佳的首位置。

之前那道题 求长度至少为 m 的最大连续子序列:
对于当前末位置 i 来说,满足的首位置在区间 [1, i-m+1] 中。
已经维护出来每个位置的前缀和 s[],那么为了使得以当前位置 i 结尾的子串元素和最大,就可以选择区间 [1, i-m] 中前缀和最小的一个值 s[j],用当前位置前缀和 s[i] 减去这个值,便可以得到以 i 位置结尾的,最大的合法区间和。O(n) 边遍历边维护即可。

当前这道题求 求长度 不超过 m 的最大连续子序列 也是一样:
对于当前末位置 i 来说,满足的首位置在区间 [i-m+1, i] 中。
为了使得以当前位置 i 结尾的子串元素和最大,就可以选择区间 [i-m, i-1] 中前缀和最小的一个值 s[j],用当前位置前缀和 s[i] 减去这个值,便可以得到以 i 位置结尾的,最大的合法区间和。

对于位置 i 不断往后走,区间 [i-m, i-1] 也是不断往后走的,始终要查询这个区间的最小值,就可以用单调队列 O(n) 来维护。

Code

#include<bits/stdc++.h>
using namespace std;

#define int long long

const int N = 300010, mod = 1e9+7;
int T, n, m;
int a[N], s[N];

signed main(){
	cin >> n >> m;
	for(int i=1;i<=n;i++) cin >> a[i], s[i] = s[i - 1] + a[i];
	
	int ans = -1e18;
	
	deque<int> que;
	for(int i=1;i<=n;i++)
	{
		if(que.size() && que.front() <= i-m-1) que.pop_front();
		
		while(que.size() && s[que.back()] >= s[i - 1]) que.pop_back();
		que.push_back(i-1);
		
		if(que.size()) ans = max(ans, s[i] - s[que.front()]);
	}
	cout << ans;
	return 0;
}

课后练习1:切蛋糕
课后练习2:King of Range(+双指针)


三、总结

把原理搞懂,能够用代码实现之后,这两种算法就掌握了。

在以后的题目中,

  • 如果需要求每个位置左边/右边第一个比其大/小的元素,就要想到用单调栈;
  • 如果需要维护一个移动区间的最值,用单调队列 O ( n ) O(n) O(n) 解决是最佳方法。
    (另外一个求区间最值的算法是 ST表,可以求任意区间的最值, O ( l o g n ) O(logn) O(logn) 预处理之后 O ( 1 ) O(1) O(1) 查询)

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

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

相关文章

PaddleNLP系列课程一:Taskflow、小样本学习、FasterTransformer

文章目录一、Taskflow1.1 前言1.2 Taskflow应用介绍1.2.1 词法分析1.2.2 命名实体识别1.2.3 文本纠错1.2.4 句法分析1.2.5 情感分析1.2.6 文本生成应用&#xff08;三行代码体验 Stable Diffusion&#xff09;1.2.7 使用技巧&#xff08;保存地址、批量推理&#xff09;二、 小…

Excel怎么转换成PDF?教你两招轻松搞定

Excel怎么转换成PDF&#xff1f;相信在工作中大家都或多或少需要转换文件的格式&#xff0c;我们会根据工作需求将word、excel、PPT、图片等文件转换成PDF文件。Excel表格是我们经常使用的一款录入数据的文件类型&#xff0c;因为excel文件打开查看时不是很方便&#xff0c;我们…

时序数据库 TDengine 3.0 参数体系使用方式汇总

在日常使用 TDengine 时&#xff0c;参数是用户们无法绕开的重要一环。深入了解参数的属性&#xff0c;生效范围&#xff0c;查询更改方式等会让我们在使用数据库的过程中更加节时高效&#xff0c;也有助于我们更加深入地理解数据库的架构体系。在 3.0 版本中&#xff0c;TDeng…

参数校验(Validator)

为什么要用validator 实战演练 1. Validated 声明要检查的参数 2. 对参数的字段进行注解标注 3. 在全局校验中增加校验异常 4. 测试 自定义参数注解 1. 比如我们来个 自定义身份证校验 注解 2. 然后自定义Validator 3. 使用自定义的注解 4.使用groups的校验 5.restful…

209数组-长度最小的子数组

题目 链接&#xff1a;209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 思路 可以采用暴力&#xff0c;两个for循环&#xff0c;不断寻找符合条件的子序列。时间复杂度为O(n^2) 代码&#xff1a; class Solution { public:int minSubArrayLen(int target, v…

【BP靶场portswigger-服务端6】信息泄露漏洞-5个实验(全)

目录 一、信息泄露漏洞 1、简述&#xff1a; 2、危害&#xff1a; 3、示例&#xff1a; 4、漏洞的产生 5、影响 6、严重程度判定 二、发现和利用信息泄露漏洞 1、模糊测试 2、使用BP扫描仪 3、使用Burp的相关工具 4、工程信息响应 三、常见来源 1、示例&#xff…

【数据篇】34 # 如何处理多元变量?

说明 【跟月影学可视化】学习笔记。 从数据到图表展现 2014 年北京市的天气历史数据&#xff08;csv 格式&#xff09; 这里使用QCharts 图表库折线图来展示平均气温 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" …

PDF转换成word免费版网页版哪个好?办公就用它

我们在工作中经常需要对PDF文件进行编辑&#xff0c;所以可以将PDF文件转换为word文件&#xff0c;这样就可以随意编辑我们想要编辑的内容了&#xff0c;不过有些小伙伴不喜欢下载客户端&#xff0c;但是又不知道PDF转换成word免费版网页版哪个好&#xff0c;为了帮助大家更好的…

微信小程序是如何设计百亿级用户画像分析系统的?

导语 | “We分析”是微信小程序官方推出的数据分析平台&#xff0c;其中画像洞察是其中一个非常重要的功能模块。微信开发工程师钟文波将描述We分析画像系统各模块是如何设计&#xff0c;在介绍基础标签模块之后&#xff0c;重点讲解用户分群模块设计。希望相关的技术实现思路&…

使用OpManager Plus进行网络运行管理

什么是网络运行管理 网络运行管理会不断跟踪网络设备及其操作&#xff0c;并在出现任何网络故障时通知技术人员团队&#xff0c;以便消除它们并主动加强网络免受停机的影响。 为什么网络运行管理很重要 借助网络操作管理工具&#xff0c;管理员可以深入了解网络的最微小细节…

springboot多模块工程单元测试jacoco统计代码覆盖率总结

jacoco统计代码覆盖率的文章一搜一大堆&#xff0c;方法也很简单&#xff0c;就是在pom中引用两个插件&#xff1a; maven-surefire-plugin jacoco-maven-plugin 其中jacoco-maven-plugin的关键配置为要有两个execution&#xff1a; 一个goal是prepare-agent&#xff0c;即…

【JavaEE】初识Spring

目录 一、创建Spring项目 二、介绍理论 一、创建Spring项目 通过maven创建Spring项目&#xff0c;我们需要借助一些工具完成工程的创建。 1.pom.xml 2.一部分示例代码 Spring提供了一个Spring Initializr使用网页版本。 然后将得到文件的内容用idea打开。然后执行会显示未连…

集群环境下解决定时任务重复执行的问题【案例分享】

【辰兮要努力】&#xff1a;hello你好我是辰兮&#xff0c;很高兴你能来阅读&#xff0c;昵称是希望自己能不断精进&#xff0c;向着优秀程序员前行&#xff01; 博客来源于项目以及编程中遇到的问题总结&#xff0c;偶尔会有读书分享&#xff0c;我会陆续更新Java前端、后台、…

机器学习中的数学原理——似然函数

这个专栏主要是用来分享一下我在 机器学习中的 学习笔记及一些 感悟&#xff0c;也希望对你的学习有帮助哦&#xff01;感兴趣的小伙伴欢迎 私信或者 评论区留言&#xff01;这一篇就更新一下《 白话机器学习中的数学——似然函数》&#xff01;什么是似然函数似然函数 定义. 在…

电商让客户等待的话术

在电商平台购物时&#xff0c;在购物前后客户难免会产生一些问题&#xff0c;客服需要先进行核对&#xff0c;或者需要转接给专员进行接待&#xff0c;在这期间&#xff0c;客户需要等候&#xff0c;这时候需要给客户发送一些等候话术。前言在电商平台购物时&#xff0c;在购物…

uni-app动态修改manifest.json中的参数

以根据不同环境配置不同的h5运行路径为例&#xff0c;动态修改h5.router.base 假设当前有三种环境 process.env.NODE_ENV developmentprocess.env.NODE_ENV testprocess.env.NODE_ENV production 在src根目录下创建modifyManifest.js文件&#xff08;一定是src&#xff09;…

渗透测试工程师的职业发展

前段时间看了一个大哥写的程序员的职业发展&#xff0c;感触很深&#xff0c;这几天晚上就参考大哥的思路结合自身的经历写一下渗透工程师的职业发展之路&#xff0c;顺便也让迷茫中的小伙伴们有个参考。 很多干渗透、安全服务、安全运维的人在干了3-5年后面对迷茫期&#xff…

2022年度猫狗粮销售数据:十大热门品牌排行榜,哪些品牌入围?

当前&#xff0c;“吸猫撸狗”正成为当代年轻人新的生活方式&#xff0c;越来越多的人乐意为了自己的“毛孩子”买单&#xff0c;这使得宠物经济快速发展。伴随着宠物食品概念越来越被消费者所接受&#xff0c;目前&#xff0c;我国宠物食品行业呈现爆发式增长&#xff0c;宠物…

电脑只有一个c盘怎么办?看我怎么一招解决!

很多朋友在网上新买了笔记本电脑&#xff0c;打开电脑后发现它只有一个磁盘&#xff0c;电脑只有一个c盘怎么办&#xff1f;下面以Windows 10系统为例进行步骤说明&#xff0c;让我们一起来解决电脑只有一个磁盘的难题吧&#xff01; 操作环境&#xff1a; 演示机型&#xff1a…

再谈什么是【组织能力】

&#xff08;1&#xff09;我过去讲过两个公式&#xff1a;从这两个公式都能看出来&#xff0c;企业管理和业务管理的巨大区别。我过去也专门讲过企业管理&#xff1a;愿景使命-文化价值观、战略目标-战略路径企业治理-企业组织、商业模式创新-品牌影响力-持续客户关系经营健康…