当前位置: 首页 > article >正文

蓝桥杯备赛 Day16 单调数据结构

单调栈和单调队列能够动态的维护,还需用1-2两个数组在循环时从单调栈和单调队列中记录答案

单调栈

要点

1.时刻保持内部元素具有单调性质的栈(先进后出),核心是:入栈时逐个删除所有"更差的点",一般可分为单调递减栈、单调递增栈、单调不减栈、单调不增栈,例如要求某个点左侧第一个比它大的点的值(或位置),如下图所示:
![[单调栈.png]]
最后一个5入栈前要把前面那个5弹出,保证严格单调递减
2.单调栈用STL的stack实现,stack的操作:

C++ 中的 STL 也提供了一个容器 `std::stack`
- 元素访问- `st.top()` 返回栈顶
- 修改- `st.push()` 插入传入的参数到栈顶- `st.emplace()`- `st.pop()` 弹出栈顶
- 容量- `st.empty()` 返回是否为空- `st.size()` 返回元素数量
百亿富翁

学习:
(1)这题就是典型的单调栈的使用,就是对于每栋楼,左边第一个比它高的楼房是哪个,右边第一个比它高的楼房是哪个(若不存在则输出−1),利用单调栈来维护下标,两个数据记录答案即可
(2)可以开两个栈,也可以开一个栈中间清空即可

while(!st1.empty()){st1.pop();
}

(3)注意删除不满足的栈元素用while循环
代码:

#include <bits/stdc++.h>using namespace std;
const int N=7e5+10;
int n,a[N],l[N],r[N];
stack<int> st1,st2;int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n;for(int i=1;i<=n;i++)	cin>>a[i];l[1]=-1;if(a[1]>a[2])	st1.emplace(1);for(int i=2;i<=n;i++){//不满足条件删除,注意用while while(!st1.empty() && a[i]>=a[st1.top()]){st1.pop();}//获取编号if(!st1.empty())	l[i]=st1.top();else l[i]=-1; //当前编号入栈st1.emplace(i); }//清空栈/*while(!st1.empty()){st1.pop();}*/ r[n]=-1;if(a[n]>a[n-1])	st2.emplace(n);for(int i=n-1;i>=1;i--){//不满足条件删除while(!st2.empty() && a[i]>=a[st2.top()]){st2.pop();}//获取编号if(!st2.empty())	r[i]=st2.top();else r[i]=-1; //当前编号入栈st2.emplace(i); }for(int i=1;i<=n;i++){cout<<l[i]<<" ";}cout<<"\n";for(int i=1;i<=n;i++){cout<<r[i]<<" ";}return 0;
}
最大区间

区间最值相关的问题
学习:
1.此题求求 L,R 使 (R−L+1)⋅min⁡(AL,AL+1,…,AR)尽可能大,其中 min 表示最小值。转化为对于每一个元素Ai,求他作为最小值的区间(l[i],r[i])(即贡献),转化为求第 i 个元素左边第一个比它小的元素的下标和右边第一个比它小的元素的下标,最后区间长度-2即可,上面转换后的问题就是典型的单调栈问题
核心:将问题转化为对每个元素的独立分析,而不是直接枚举所有可能的区间(O(n^2)->O(n))
2.l数组和r数组的默认值:

vector<int> l(n+1,0);//l[i]记录第i个元素左边第一个比他小的元素序号,默认是0(因为答案是要序号+1的,表示能到第一个元素) vector<int> r(n+1,n+1);//r[i]记录第i个元素右边第一个比他小的元素序号,默认是n+1(因为答案是要序号-1的,表示能到最后一个元素) 

3.保证栈是严格单调递增的,注意有=号
代码:

#include <bits/stdc++.h>using namespace std;
typedef long long ll;
const int N=3e5+10;
int n,a[N]; //l[i],l[i]记录第i个元素左边第一个比他小的元素序号,r[i]记录第i个元素右边第一个比他小的元素序号 
stack<int> st;
ll res;int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n;for(int i=1;i<=n;i++)	cin>>a[i];vector<int> l(n+1,0);//l[i]记录第i个元素左边第一个比他小的元素序号,默认是0(因为答案是要序号+1的,表示能到第一个元素) vector<int> r(n+1,n+1);//r[i]记录第i个元素右边第一个比他小的元素序号,默认是n+1(因为答案是要序号-1的,表示能到最后一个元素) //先算左边比自己小的元素序号 for(int i=1;i<=n;i++){//严格单调递增(有=号) while(!st.empty() && a[st.top()]>=a[i])	st.pop();if(!st.empty())	l[i]=st.top();st.emplace(i);}//清空栈while(!st.empty())	st.pop();//再算右边比自己小的元素序号 for(int i=n;i>=1;i--){//严格单调递增(有=号) while(!st.empty() && a[st.top()]>=a[i])	st.pop();if(!st.empty())	r[i]=st.top();st.emplace(i);} for(int i=1;i<=n;i++){//cout<<"i="<<i<<" l[i]="<<l[i]<<" r[i]="<<r[i]<<endl;//注意要-2 res=max(res,(ll)(r[i]-l[i]+1-2)*a[i]);}cout<<res;return 0;
}
四元组问题

学习:
(1)此题我根据条件:
四个不同的下标 a,b,c,d,使得 a < b < c < d ,并且 nums[d] < nums[c]< nums[a]< nums[b]
想到寻找每个元素左边和右边第一个比它小的元素的下标,此元素就是b,然后左边的就是a,右边的就是c,如果nums[c]>nums[a],那么就循环c=r[c],不断缩小nums[c],直到nums[c]<nums[a],或者不存在,最后判断nums[d]=nums[r[c]]存不存在即可,用单调栈解决
代码:

#include <bits/stdc++.h>using namespace std;
const int N=5e5+10;
int a[N],n;
stack<int> st;
bool res;
int l[N],r[N];int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n;for(int i=1;i<=n;i++)	cin>>a[i];//严格单调递增 for(int i=1;i<=n;i++){while(!st.empty() && a[st.top()]>=a[i])	st.pop();if(!st.empty())	l[i]=st.top();st.emplace(i);}while(!st.empty())	st.pop();for(int i=n;i>=1;i--){while(!st.empty() && a[st.top()]>=a[i])	st.pop();if(!st.empty())	r[i]=st.top();st.emplace(i);}//遍历寻找b元素for(int i=1;i<=n;i++){if(res)	break;int ta=l[i],c=r[i];if(ta==0 || c==0)	continue;//让a[c]<a[ta] while(a[ta]<=a[c]){c=r[c];if(c==0)	break;}if(c==0)	continue;//寻找dif(r[c])	res=true; } cout<<(res?"YES":"NO");return 0;
}

单调队列

要点

1.队内元素具有单调性质,一般将“下标”作为队列中的元素,而不是“元素值”
2.队头是“最优的元素”,后面是候选元素,每次入队时会将“没有价值的元素”直接删除
3.常用于处理固定长度的区间最值(常用于滑动窗口问题)
4.单调队列和优先队列的区别:
(1)单调队列一般用双端队列deque实现,需要在队头和队尾进行操作。而优先队列用STL的priority_queue实现(本质是堆)
(2)单调队列保持队列中元素的单调性,而优先队列不保证单调性,只保证队头元素是最大或最小。
(3)单调队列常用于滑动窗口问题,优先队列常用于需要动态获取最大或最小元素的场景。
5.双端队列操作:

C++ 中的 STL 也提供了一个容器 `std::deque`(双端队列)
- 元素访问- `dq.front()` 返回队头元素 - `dq.back()` 返回队尾元素- `dq.at(index)` 返回指定索引位置的元素(带边界检查)- `dq[index]` 返回指定索引位置的元素(无边界检查)
- 修改- `dq.push_front(value)` 在队头插入元素  - `dq.emplace_front(args...)` 在队头直接构造元素 - `dq.push_back(value)` 在队尾插入元素  - `dq.emplace_back(args...)` 在队尾直接构造元素  - `dq.pop_front()` 移除队头元素  - `dq.pop_back()` 移除队尾元素 - `dq.insert(iterator, value)` 在指定位置插入元素 - `dq.erase(iterator)` 移除指定位置的元素- `dq.clear()` 清空所有元素 
- 容量- `dq.empty()` 返回是否为空 - `dq.size()` 返回元素数量   - `dq.max_size()` 返回可容纳的最大元素数量
买蛋糕

学习:
(1)典型的用单独队列来求固定长度为k的区间的最值(最大值和最小值都可以),用双端队列deque实现,比如要求长度为k的最小值,让双端队列单掉递增,队首front是最小值序号,要判断队首元素是否在(i-k+1,i)中,不再则弹出。判断要插入元素和队尾元素的大小,如果小于队尾元素,则弹出队尾元素。最终把队首元素放入mi数组中
(2)此题涉及(a / b) % mod,且mod= 998244353998244353是质数,可以用费马小定理+快速幂求逆元,得 ( a / b ) % m o d = a ∗ b ( m o d − 2 ) % m o d (a/b)\%mod=a*b^{(mod-2)}\%mod (a/b)%mod=ab(mod2)%mod
[[Day17 数学]]
(3)最好有取模的都用long long,可以使用以下技巧快速修改:

#define int long longsigned main(){ //不能写int}

代码:

#include <bits/stdc++.h>#define int long longusing namespace std;
const int N=1e5+10,M=998244353;
int n,k,x,a[N],sum,cnt;
deque<int> dq1,dq2;//dq1单调递增,队头是最小值序号,dq2单调递减,队头是最大值序号 
int mx[N],mi[N]; //到k为止位置的最小值和最大值 int binpow(int base,int power){int res=1;while(power){if(power & 1){res=(res*base)%M;}base=(base*base)%M;power>>=1; //有个= }return res;
}signed main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>k>>x;for(int i=1;i<=n;i++)	cin>>a[i];//求长度为k的区间的最小值for(int i=1;i<=n;i++){//队头序号不在(i-k+1,i)之间则弹出,维护长度为kwhile(!dq1.empty() && dq1.front()<i-k+1)	dq1.pop_front();//插入元素比队尾元素小弹出队尾元素while(!dq1.empty() && a[i]<a[dq1.back()])	dq1.pop_back();//插入元素序号到队尾dq1.emplace_back(i);//获取到i位置为止的最小值mi[i]=a[dq1.front()]; } //求长度为k的区间的最大值for(int i=1;i<=n;i++){//队头序号不在(i-k+1,i)之间则弹出,维护长度为kwhile(!dq2.empty() && dq2.front()<i-k+1)	dq2.pop_front();//插入元素比队尾元素大弹出队尾元素while(!dq2.empty() && a[i]>a[dq2.back()])	dq2.pop_back();//插入元素序号到队尾dq2.emplace_back(i);//获取到i位置为止的最大值mx[i]=a[dq2.front()]; }//获取结果for(int i=k;i<=n;i++){if((mx[i]-mi[i])<=x)	cnt++;} cout<<cnt*binpow(n-k+1,M-2)%M<<endl;return 0;
}
子矩阵

学习:
(1)此题就是一维求长度为k的区间的最值的二维拓展,求区间长a,宽b的最大值和最小值,用双端队列实现单调队列,内部元素就是位置(i,j)的有序对即可
代码:

#include <bits/stdc++.h>using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N=1005,mod=998244353;
ll a[N][N],res;
deque<PII> dqmin,dqmax;//队首是最小值、最大值,对内元素为(i,j) 
int n,m,ta,b;
ll resmin[N][N],resmax[N][N];int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m>>ta>>b;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>a[i][j];}}//算最小值 for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){//不在(i-ta+1,i)(j-b+1,j)内出队列while(!dqmin.empty() && (dqmin.front().first<(i-ta+1) || dqmin.front().second<(j-b+1)))	dqmin.pop_front();//插入元素小于队尾元素,弹出队尾元素while(!dqmin.empty() && a[i][j]<a[dqmin.back().first][dqmin.back().second])	dqmin.pop_back();//插入元素到队尾dqmin.emplace_back(i,j);  resmin[i][j]=a[dqmin.front().first][dqmin.front().second];	}}//算最大值 for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){//不在(i-ta+1,i)(j-b+1,j)内出队列while(!dqmax.empty() && (dqmax.front().first<(i-ta+1) || dqmax.front().second<(j-b+1)))	dqmax.pop_front();//插入元素大于队尾元素,弹出队尾元素while(!dqmax.empty() && a[i][j]>a[dqmax.back().first][dqmax.back().second])	dqmax.pop_back();//插入元素到队尾dqmax.emplace_back(i,j);  resmax[i][j]=a[dqmax.front().first][dqmax.front().second];	}}//算结果for(int i=ta;i<=n;i++){for(int j=b;j<=m;j++){ll t=(resmin[i][j]*resmax[i][j])%mod;res=(res+t)%mod;}} cout<<res;return 0;
}
游戏

学习:
(1)典型的用单调队列求区间最值问题
(2)学会输出浮点数(保留2位小数)
cout<<fixed<<setprecision(2)<<res;
(3)最后结果利用数学公式总结最大值和最小值的和都出现了(n-k+1)次,不用O(n^n)遍历算,O(n)就能解决,且还能约掉一个(n-k+1),如果不约,不能直接除以(n-k+1)*(n-k+1),会越界
代码:

#include <bits/stdc++.h>using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,k,a[N];
deque<int> dqmin,dqmax;
int minn[N],maxn[N];
ll sum,cnt,summin,summax;
double res;int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>k;for(int i=1;i<=n;i++)	cin>>a[i];for(int i=1;i<=n;i++){while(!dqmin.empty() && dqmin.front()<i-k+1)	dqmin.pop_front();while(!dqmin.empty() && a[dqmin.back()]>a[i])	dqmin.pop_back();dqmin.emplace_back(i);if(i>=k)	summin+=a[dqmin.front()];	}for(int i=1;i<=n;i++){while(!dqmax.empty() && dqmax.front()<i-k+1)	dqmax.pop_front();while(!dqmax.empty() && a[dqmax.back()]<a[i])	dqmax.pop_back();dqmax.emplace_back(i);if(i>=k)	summax+=a[dqmax.front()];}sum=(n-k+1)*(n-k+1);/*for(int i=k;i<=n;i++){for(int j=k;j<=n;j++){cnt+=(maxn[i]-minn[j]);}}*/cout<<fixed<<setprecision(2)<<(summax-summin)*1.0/(n-k+1);return 0;
}

优先队列

要点:

1.动态维护和快速访问优先级最高(或最低)元素(只能访问队首元素,不能像双端队列既能访问队首元素,也能访问队尾元素)的问题
2.优先队列操作:

C++ 中的 STL 提供了一个容器 `std::priority_queue`(优先队列),它是一种特殊的队列,元素按照优先级排序,默认情况下最大元素位于队首。
- 元素访问- `pq.top()` 返回队首元素(优先级最高的元素),注意这里没有 `front()` 方法,因为优先队列的逻辑是总是访问优先级最高的元素。
- 修改- `pq.push(value)` 在队列中插入元素,插入后队列会自动调整元素顺序以保证队首元素优先级最高。- `pq.emplace(args...)` 在队列中直接构造元素,同样插入后会自动调整顺序。- `pq.pop()` 移除队首元素(优先级最高的元素)。
- 容量- `pq.empty()` 返回队列是否为空。- `pq.size()` 返回队列中元素的数量。- `pq.max_size()` 返回队列可容纳的最大元素数量。
合并果子

学习
不断找最小的两个元素,使用优先队列获得,加起来得到t,结果加上t,再把t放到优先队列中
代码:

#include <bits/stdc++.h>using namespace std;
typedef long long ll;
const int N=1e4+10;
int n,a;
ll res; 
priority_queue<ll,vector<ll>,greater<ll>> pq;//队首是最小值 int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n;for(int i=1;i<=n;i++){cin>>a;pq.emplace(a);}if(pq.size()==1){res=pq.top();}while(pq.size()>1){int t1=pq.top();//cout<<"t1="<<t1<<endl;pq.pop();int t2=pq.top();//cout<<"t2="<<t2<<endl;pq.pop();res+=(ll)t1+t2;//cout<<"res="<<res<<endl;pq.emplace(t1+t2);}cout<<res;return 0;
}
最大开支

思想值得学习
学习:
1.此题要用优先队列动态维护每个项目的边际成本(即每增加一个人时,总成本的变化),通过计算对第i个项目从x-1个人增加到x个人所需钱的差,然后放到优先队列中,答案累加边际成本即可(含义是增加一个人的成本增加的最大值(不用管哪个项目)),最多n个人
代码:

#include <bits/stdc++.h>using namespace std;
typedef long long ll;
const int M=1e5+10;
int n,m,k[M],b[M],cnt[M];
ll res;
priority_queue<ll> pq;//返回第i个项目增加1个人所增加的钱数(即从x-1增加到x人)
//x(kx+b)-(x-1)(k(x-1)+b)=k(2x-1)+b
ll getCost(int i,int x){//ll res=max((ll)x*(k[i]*x+b[i])-(ll)(x-1)*(k[i]*(x-1)+b[i]),(ll)0);ll res=max((ll)k[i]*(2*x-1)+b[i],(ll)0);return res;
} int main(){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);cin>>n>>m;for(int i=1;i<=m;i++){cin>>k[i]>>b[i];}//算对于第i个项目增加1个人所需增强的钱数放到优先队列中 for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){//如果第i个项目j个人相对于j-1个人是增加钱的,放到优先队列中if(getCost(i,j)){pq.emplace(getCost(i,j)); }else	break;}}//计算num次(最多n个人,即最多增加n次>0的钱,但也有可能pq大小小于n,0不在里面)int num=min((int)pq.size(),n);while(num--){res+=pq.top();pq.pop();} cout<<res;//下面这种比较好理解int num=n;while(!pq.empty() && num>0){res+=pq.top();pq.pop();num--;}return 0;
}

相关文章:

蓝桥杯备赛 Day16 单调数据结构

单调栈和单调队列能够动态的维护&#xff0c;还需用1-2两个数组在循环时从单调栈和单调队列中记录答案 单调栈 要点 1.时刻保持内部元素具有单调性质的栈(先进后出),核心是:入栈时逐个删除所有"更差的点",一般可分为单调递减栈、单调递增栈、单调不减栈、单调不增…...

轻量级爬虫框架Feapder入门:快速搭建企业级数据管道

一、目标与前置知识 1. 目标概述 本教程的主要目标是&#xff1a; 介绍轻量级爬虫框架 Feapder 的基本使用方式。快速搭建一个采集豆瓣电影数据的爬虫&#xff0c;通过电影名称查找对应的电影详情页并提取相关信息&#xff08;电影名称、导演、演员、剧情简介、评分&#xf…...

golang gmp模型分析

思维导图&#xff1a; 1. 发展过程 思维导图&#xff1a; 在单机时代是没有多线程、多进程、协程这些概念的。早期的操作系统都是顺序执行 单进程的缺点有&#xff1a; 单一执行流程、计算机只能一个任务一个任务进行处理进程阻塞所带来的CPU时间的浪费 处于对CPU资源的利用&…...

深入理解Java Optional:告别NullPointerException的优雅方式

大家好&#xff01;今天我们来聊聊Java 8引入的一个超实用类 - Optional。不是那个让你重启电脑的CtrlAltDel哦&#xff01;&#x1f604; 这是一个能让我们优雅处理null值的工具类&#xff0c;彻底告别烦人的NullPointerException&#xff01; 一、为什么需要Optional&#x…...

【算法竞赛】树上最长公共路径前缀(蓝桥杯2024真题·团建·超详细解析)

目录 一、题目 二、思路 1. 问题转化&#xff1a;同步DFS走树 2. 优化&#xff1a;同步DFS匹配 3. 状态设计&#xff1a;dfs参数含义 4. 匹配过程&#xff1a;用 map 建立权值索引 5. 终止条件&#xff1a;无法匹配则更新答案 6. 总结 三、完整代码 四、知识点总…...

【windows10】基于SSH反向隧道公网ip端口实现远程桌面

【windows10】基于SSH反向隧道公网ip端口实现远程桌面 1.背景2.SSH反向隧道3.远程连接电脑 1.背景 ‌Windows 10远程桌面协议的简称是RDP&#xff08;Remote Desktop Protocol&#xff09;‌。 RDP是一种网络协议&#xff0c;允许用户远程访问和操作另一台计算机。 远程桌面功…...

Python----概率论与统计(贝叶斯,朴素贝叶斯 )

一、贝叶斯 1.1、贝叶斯定理 贝叶斯定理&#xff08;Bayes Theorem&#xff09;也称贝叶斯公式&#xff0c;是关于随机事件的条件概率的定理 贝叶斯的的作用&#xff1a;根据已知的概率来更新事件的概率。 1.2、定理内容 提示&#xff1a; 贝叶斯定理是“由果溯因”的推断&…...

NO.88十六届蓝桥杯备战|动态规划-多重背包|摆花(C++)

多重背包 多重背包问题有两种解法&#xff1a; 按照背包问题的常规分析⽅式&#xff0c;仿照完全背包&#xff0c;第三维枚举使⽤的个数&#xff1b;利⽤⼆进制可以表⽰⼀定范围内整数的性质&#xff0c;转化成01 背包问题。 ⼩建议&#xff1a;并不是所有的多重背包问题都能…...

vue项目打包里面pubilc里的 tinymce里的js文件问题

以下是解决 Vue 项目打包后 public/tinymce 中 JS 文件路径问题的完整方案&#xff1a; 问题原因 当使用 public 目录存放静态资源时&#xff0c;Vue CLI 默认会将 public 下的文件 直接复制到打包目录的根路径&#xff0c;但以下操作可能导致路径错误&#xff1a; 开发环境使…...

Python星球日记 - 第18天:小游戏开发(猜数字游戏)

🌟引言: 上一篇:Python星球日记 - 第17天:数据可视化 名人说:路漫漫其修远兮,吾将上下而求索。(屈原《离骚》) 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、游戏概述与原理1. 游戏基本规则2. 编程知识点3.猜数字游戏流程图二、游戏逻辑设计…...

爬虫抓包工具和PyExeJs模块

我们在处理一些网站的时候, 会遇到一些屏蔽F12, 以及只要按出浏览器的开发者工具就会关闭甚至死机的现象. 在遇到这类网站的时候. 我们可以使用抓包工具把页面上屏蔽开发者工具的代码给干掉. Fiddler和Charles 这两款工具是非常优秀的抓包工具. 他们可以监听到我们计算机上所…...

无人机击落技术难点与要点分析!

一、技术难点 1. 目标探测与识别 小型化和低空飞行&#xff1a;现代无人机体积小、飞行高度低&#xff08;尤其在城市或复杂地形中&#xff09;&#xff0c;雷达和光学传感器难以有效探测。 隐身技术&#xff1a;部分高端无人机采用吸波材料或低可探测设计&#xff0c;进…...

2025年Java无服务器架构实战:AWS Lambda与Spring Cloud Function深度整合

摘要 &#x1f4dd; 本文深入探讨如何在2025年Java生态中实现AWS Lambda与Spring Cloud Function的无缝整合。我们将从基础概念讲起&#xff0c;逐步深入到实际部署、性能优化和最佳实践&#xff0c;通过详实的代码示例展示如何构建高效、可扩展的无服务器Java应用。 目录 &a…...

LeetCode 题目 「二叉树的右视图」 中,如何从「中间存储」到「一步到位」实现代码的优化?

背景简介 在 LeetCode 的经典题目 「二叉树的右视图」 中&#xff0c;我们需要返回从右侧看一棵二叉树时所能看到的节点集合。每一层我们只能看到最右边的那个节点。 最初&#xff0c;我采用了一个常规思路&#xff1a;层序遍历 每层单独保存节点值 最后提取每层最后一个节…...

8.第二阶段x64游戏实战-string类

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;7.第二阶段x64游戏实战-分析人物属性 string类是字符串类&#xff0c;在计算机中…...

Go语言sync.Mutex包源码解读

互斥锁sync.Mutex是在并发程序中对共享资源进行访问控制的主要手段&#xff0c;对此Go语言提供了非常简单易用的机制。sync.Mutex为结构体类型&#xff0c;对外暴露Lock()、Unlock()、TryLock()三种方法&#xff0c;分别用于阻塞加锁、解锁、非阻塞加锁操作&#xff08;加锁失败…...

C++实现文件断点续传:原理剖析与实战指南

文件传输示意图 一、断点续传的核心价值 1.1 大文件传输的痛点分析 网络闪断导致重复传输&#xff1a;平均重试3-5次。 传输进度不可回溯&#xff1a;用户无法查看历史进度。 带宽利用率低下&#xff1a;每次中断需从头开始。 1.2 断点续传技术优势 指标传统传输断点续传…...

MySQL中FIND_IN_SET函数与INSTR函数用法解析

一、功能定义与语法 1、FIND_IN_SET函数 语法&#xff1a;FIND_IN_SET(str, strlist) 功能&#xff1a;在逗号分隔的字符串列表&#xff08;strlist&#xff09;中查找精确匹配的子字符串&#xff08;str&#xff09;&#xff0c;并返回其位置&#xff08;从1开始&#xff09…...

Python贝叶斯回归、强化学习分析医疗健康数据拟合截断删失数据与参数估计3实例

全文链接&#xff1a;https://tecdat.cn/?p41391 在当今数据驱动的时代&#xff0c;数据科学家面临着处理各种复杂数据和构建有效模型的挑战。本专题合集聚焦于有序分类变量处理、截断与删失数据回归分析以及强化学习模型拟合等多个重要且具有挑战性的数据分析场景&#xff0c…...

Git 协同开发的常用操作

1. 单仓库&#xff08;多分支开发&#xff09; 从远程拉取代码 git clone https://gitee.com/...查看当前分支 git branch -- *master创建并切换到你的开发分支&#xff08;my-dev&#xff09; git checkout -b my-dev查看当前分支 git branch -- marster -- *my-dev提交代…...

微信小程序 -- 原生封装table

文章目录 table.wxmltable.wxss注意 table.js注意 结果数据结构 最近菜鸟做微信小程序的一个查询功能&#xff0c;需要展示excel里面的数据&#xff0c;但是菜鸟找了一圈&#xff0c;也没发现什么组件库有table&#xff0c;毕竟手机端好像确实不太适合做table&#xff01; 菜鸟…...

分布式文件存储系统FastDFS

文章目录 1 分布式文件存储1_分布式文件存储的由来2_常见的分布式存储框架 2 FastDFS介绍3 FastDFS安装1_拉取镜像文件2_构建Tracker服务3_构建Storage服务4_测试图片上传 4 客户端操作1_Fastdfs-java-client2_文件上传3_文件下载4_获取文件信息5_问题 5 SpringBoot整合 1 分布…...

ZKmall开源商城服务端验证:Jakarta Validation 详解

ZKmall开源商城基于Spring Boot 3构建&#xff0c;其服务端数据验证采用Jakarta Validation API​&#xff08;原JSR 380规范&#xff09;&#xff0c;通过声明式注解与自定义扩展机制实现高效、灵活的数据校验体系。以下从技术实现、核心能力、场景优化三个维度展开解析&#…...

深度分页及优化建议

深度分页的定义 深度分页是指在分页查询中&#xff0c;当用户请求非常靠后的页面时&#xff0c;数据库需要处理大量数据&#xff0c;导致查询性能显著下降的情况。例如&#xff0c;一个查询结果有 100 万条记录&#xff0c;而用户要查询第 999 页&#xff08;每页 10 条记录&a…...

电网电能质量分析:原理、算法及实际应用

一、引言 在现代社会&#xff0c;电力供应的稳定性和可靠性对工业生产、社会生活的各个方面都至关重要。电能质量作为衡量电力系统供电能力的关键指标&#xff0c;其优劣直接影响到电力设备的运行效率、使用寿命以及生产过程的稳定性。随着电力系统规模的不断扩大&#xff0c;新…...

学透Spring Boot — 017. 魔术师—Http消息转换器

本文是我的专栏《学透Spring Boot》的第17篇文章&#xff0c;了解更多请移步我的专栏&#xff1a; 学透 Spring Boot_postnull咖啡的博客-CSDN博客 目录 HTTP请求和响应 需求—新的Media Type 实现—新的Media Type 定义转换器 注册转换器 编写Controller 测试新的medi…...

BOE(京东方)旗下控股子公司“京东方能源”成功挂牌新三板 以科技赋能零碳未来

2025年4月8日,BOE(京东方)旗下控股子公司京东方能源科技股份有限公司(以下简称“京东方能源”)正式通过全国中小企业股份转让系统审核,成功在新三板挂牌(证券简称:能源科技,证券代码:874526),成为BOE(京东方)自物联网转型以来首个独立孵化并成功挂牌的子公司。此次挂牌是BOE(京…...

Airflow集成Lark机器人

🥭1. 实现目标 🕐 通过自定义函数,实现Lark机器人告警功能 🕐 通过Lark机器人代替邮件数据的发送功能 🥭2.自定义函数实现 from airflow import DAG from airflow.operators.python_operator import PythonOperator from airflow.models import Variable import requ…...

Git使用与管理

一.基本操作 1.创建本地仓库 在对应文件目录下进行&#xff1a; git init 输入完上面的代码&#xff0c;所在文件目录下就会多一个名为 .git 的隐藏文件&#xff0c;该文件是Git用来跟踪和管理仓库的。 我们可以使用 tree 命令&#xff08;注意要先下载tree插件&#xff09…...

计算机网络——传输层(Udp)

udp UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议 &#xff09;是一种无连接的传输层协议&#xff0c;它在IP协议&#xff08;互联网协议&#xff09;之上工作&#xff0c;为应用程序提供了一种发送和接收数据报的基本方式。以下是UDP原理的详细解释&…...