本章内容

二分
分治

 

当你把疑惑一劈为二,困境就只剩下一半。

一、二分查找

1. 何谓“二分”?

“二分”本质是一种 对单调现象反复折半 的搜索思想。

单调现象:随变量增大,目标状态只会保持“假→真”或“真→假”一次性跃迁。
每一次比较都把搜索区间削去一半,直到锁定唯一位置或满足精度要求。


2. 必备前提

  1. 1. 单调性
    • 离散序列:数组按非降或非升排序;
    • 判定函数check(x) 先假后真(或先真后假),可以理解为 00001111 或者 11110000 模式,真假有个临界值。
  1. 2. 可随机访问或可 O(1) 判定
    • • 访问 mid 的代价必须远小于遍历整区间。
  1. 3. 边界已知
    • • 必须能给出最小可能值 l 和最大可能值 r(或 r+1)。

3. 常见两大写法对比

写法

区间

循环条件

mid 取法

更新

闭区间

[l,r]

while(l ≤ r)

mid = l + (r-l)/2

l = mid+1

/ r = mid-1

半开区间

[l,r)

while(l < r)

mid = l + (r-l)/2

mid = l + (r-l+1)/2

r = mid

/ l = mid

只要三件套(区间定义、循环条件、更新规则)保持一致,就不会死循环;混写一定出错。


4. 两大写法举例

4.1 半开区间

① 数组已按非降排序,需要

  • • 查找元素 k 的下标,或找 最左 ≥ k 的边界(左边界)

模版

① 设 l = 最小下标,r = n     // 半开区间 [l, r)
② while (l < r):
③     mid = l + (r-l)/2
④     if a[mid] >= k :
⑤         r = mid           // 保留 mid,收缩右端
⑥     else
⑦         l = mid + 1       // 舍弃 mid 及其左侧
⑧ 返回 l
  • 区间语义:始终保持 [l,r):存在 k 值,lr 指向最左边 k 位置(若存在多个 k ),若不在 k,指向“满足条件”的第一项位置。

举例: 1 2 2 2 4 5 若查询 2 ,则指向第一个 2 的位置,若查询 3 ,则指向第一个 4 的位置。

  • 收敛性r-l 每轮至少减半,循环次数 ≤ ⌈log₂(区间长度)⌉。
  • 全小时越界:可以提前判断 k > a[n] ,二分查找后,即使 k > a[n] ,指针 l 依然会停留在 n

② 数组已按非降排序,需要

  • • 查找元素 k 的下标,或找 最右 ≤ k 的边界(右边界)

模版

① 设 l = 最小下标,r = n     // 半开区间 [l, r)
② while (l < r):
③     mid = l + (r-l+1)/2
④     if a[mid] <= k :
⑤         l = mid           // 保留 mid,收缩左端
⑥     else
⑦         r = mid - 1       // 舍弃 mid 及其右侧
⑧ 返回 l
  • 区间语义:始终保持 [l,r):存在 k 值,lr 指向最右边 k 位置(若存在多个 k ),若不在 k,指向“满足条件”的最后项位置。

举例: 1 2 2 2 4 5 若查询 2 ,则指向最后一个 2 的位置,若查询 3 ,则指向最右一个 2 的位置。

  • 收敛性r-l 每轮至少减半,循环次数 ≤ ⌈log₂(区间长度)⌉。
  • 全大时越界:可以提前判断 k < a[1] ,二分查找后,即使 k < a[1] ,指针 l 依然会停留在 1

4.2 全闭区间

① 数组已按非降排序,需要

  • • 查找元素 k 的下标,或找 最左 ≥ k 的边界

图:闭区间二分循环结束时的左右指针位置(查找第一个 4)

模版

① 设 l = 最小下标,r = n,ans = -1     
② while (l <= r):
③     mid = l + (r-l)/2
④     if a[mid] >= k :
⑤         ans = mid            // 记录答案
⑥         r = mid - 1       // 舍弃 mid,及其右侧
⑦     else
⑧         l = mid + 1       // 舍弃 mid,及其左侧
⑨ 返回 ans
  • 边界情况:k > a[n],则 l 指向 n+1r 指向 nans = -1 ,可提前特判。

k < a[1],则 l 指向 1r 指向 0ans = 1


② 数组已按非降排序,需要

  • • 查找元素 k 的下标,或找 最左 ≤ k 的边界

图:闭区间二分循环结束时的左右指针位置(查找最后一个 4)

模版

① 设 l = 最小下标,r = n,ans = -1     
② while (l <= r):
③     mid = l + (r-l+1)/2
④     if a[mid] <= k :
⑤         ans = mid            // 记录答案⑨
⑥         l = mid + 1       // 舍弃 mid,及其左侧
⑦     else
⑧         r = mid - 1       // 舍弃 mid,及其右侧
⑨ 返回 ans
  • 边界情况:k < a[1],则 l 指向 1r 指向 0ans = -1 ,可提前特判。

k > a[n],则 l 指向 4r 指向 3ans = 3


5. 离散与连续

  • 离散二分 —— 目标集合为整数下标或枚举值,循环到空区间即停止。
  • 连续二分 —— 目标区间是实数,常用 while(r - l > eps),每次取中点判断函数符号或方向。典型:√x、几何最小距离。

6. 复杂度

  • 时间O(log₂N) —— N 为搜索区间长度或上界 − 下界。
  • 空间:迭代 O(1);递归多消耗 O(log₂N) 栈。

7. 坑总结

  1. 1. 溢出
    mid = (l + r) / 2 可能超出 32-bit;改用 l + (r-l)/2 或用 64-bit 变量。
  2. 2. 死循环
    更新规则不严格收缩区间(如把 r = mid 写成 r = mid-1 却仍用半开区间)。
  3. 3. 答案不存在
    返回下标前需验证 l < n && a[l] ≥ k,否则越界或误判。
  4. 4. 不满足单调性
    例如峰值数组、循环升序等,需要改成“旋转二分”或先判断段。

8. 简述 lower_bound, upper_bound

8.1 它们是什么?

名称

头文件

作用

单调含义

lower_bound

<algorithm>

返回首个 ≥ val

的位置

保证区间左侧都 < val

upper_bound

<algorithm>

返回首个 > val

的位置

保证区间左侧都 ≤ val

二者都以折半查找实现,要求传入的范围已经按比较准则排好序;时间复杂度 O(log n),在C++中它们返回的是一个 迭代器,返回值为指向结果位置的 随机迭代器。若搜索失败,都会返回“末尾迭代器”——即 last 本身。


8.2 基本原型
template<class It, class T>
It lower_bound(It first, It last, const T& val);           // 默认 operator<template<class It, class T, class Cmp>
It lower_bound(It first, It last, const T& val, Cmp cmp);  // 自定义比较// upper_bound 同理,只是比较改成 !(val < *it) 内部条件

区间 [first, last) 必排好序且与 cmp(若提供)一致;否则行为未定义。


8.3. 最常见三种用法
1) 在 vector 中查找
#include <bits/stdc++.h>
using namespace std;int main(){ios::sync_with_stdio(false);vector<int> v = {1, 2, 4, 4, 5, 7};int k = 4;auto it1 = lower_bound(v.begin(), v.end(), k);   // -> v[2]auto it2 = upper_bound(v.begin(), v.end(), k);   // -> v[4]cout << "首 ≥ 4 的下标: " << it1 - v.begin() << "\n";cout << "首  > 4 的下标: " << it2 - v.begin() << "\n";
}

输出

首 ≥ 4 的下标: 2
首  > 4 的下标: 4

可用 it2 - it1 快速得到 值为 4 的出现次数


2) 维持有序插入(离散化、优先表)
void ins(vector<int>& v,int x){auto it = lower_bound(v.begin(), v.end(), x); // 找到插入位v.insert(it, x);                              // 保证仍有序
}

3) 筛选区间 [L, R] 内元素
vector<int> v = {1,3,3,6,8,9,13};
int L = 3, R = 8;
auto l = lower_bound(v.begin(), v.end(), L);   // 首 ≥ L
auto r = upper_bound(v.begin(), v.end(), R);   // 首  > R
for(auto it=l; it!=r; ++it) cout<<*it<<" ";    // 打印 3 3 6 8

8.4 与 set / multiset

set::lower_boundupper_bound 成员函数与算法版功能完全一致、但更方便:

set<int> st = {2,5,7};
int x = 4;
auto it = st.lower_bound(x);   // 指向 5
if(it != st.end()) cout<<*it;

multiset 同理,只是可保留重复值,upper_bound 常用来删除所有等于某值的元素区间。


8.5 自定义比较

例如把一串字典序字符串按长度有序存储,然后查“首个长度 ≥ k”:

vector<string> vs = {"a","ab","abcd","abcdef"};
int k = 4;
auto cmp = [](const string& a,const string& b){ return a.size() < b.size(); };
auto it = lower_bound(vs.begin(), vs.end(), string(k,'?'), cmp);
cout<<*it;           // 输出 "abcd"

传入的 val 只需要同类型或可被比较即可;上例用长度为 k 的随意字符串作“哑值”。


8.6 易错点 & 经验
  1. 1. 未排序就调用 → UB,不会抛异常而是产生随机结果。
  2. 2. 返回末尾:写循环前务必先判 it != container.end()
  3. 3. vector<int> a; int idx = lower_bound(a.begin(), a.end(), k) - a.begin();
    记得 减去首迭代器 才得下标。
  4. 4. 若区间很大,尽量传 原生指针iterator,而非拷贝大对象。
  5. 5. 与 binary_search 区分:后者仅返回 bool,无法获取位置。

8.7 快速对照

目标

调用

说明

第一个 ≥ k

lower_bound

“左边界”

第一个 > k

upper_bound

“右边界”

值区间 [k₁,k₂]

lb = lower_bound(k₁); ub = upper_bound(k₂);

[lb,ub)

即范围

首个 ≤ k

auto it = upper_bound(k); if(it==begin) 无; else --it;

upper_bound--

二、二分答案

1. 引子:为何“二分答案”在算法竞赛屡试不爽?

在信息学题目中,我们常常遇到这样的描述:

给定一个判定函数 check(x),当自变量 足够小时返回 false,当 足够大时返回 true
求最小的 ,使 check(x)true

这类“单调可行性”问题贯穿了载重运输、分段切割、最小化最大值、资源调度、连续数值逼近等整整一个大族。与其对每个 穷举测试,我们完全可以借助二分——让待搜索区间一次次折半,把复杂度从线性 降成对数 。OIer 便把这种“在结果区间上二分”的做法称为 “二分答案”,以区别于传统“在有序数组里找元素”的 索引二分


2. 核心概念与理论根基

2.1 单调现象

若存在某个临界点 ,使得:

那么我们说 check 对定义域 单调不降(也有题目相反,先真后假,本质对称)。此时,只要能在区间 内找到 check(x) 首次变为 true 的位置,即得最优答案 。

2.2 二分公式与循环不变式

最常用的迭代模板(求最小真值)如下:

long long sol(long long L, long long R){   while(L < R){long long M = L + (R-L)/2;          // 防溢出if(check(M)) R = M;               // M 可行 → 抛弃右半else         L = M + 1;           // M 不行 → 抛弃左半含 M}return L;                                   // L==R
}

循环不变式

  • • 每轮保持 check(R)=truecheck(L-1)=false(若定义);
  • • 区间长度至少减半;故迭代次数 ≤ 。

若要求最大不可行,只需把“可行时收右端”改为“可行时收左端”(左边界改右边界),并使用 M = L + (R-L+1)/2 (向上取整),即可杜绝死循环。

2.3 整数域 vs 连续域
  • 离散整数:循环条件 while(L<R),最终 L(R) 即整数答案。
  • 实数/浮点:循环 while(R-L > eps),或指定次数 for(i=0;i<60;i++);结束后常取 L(L+R)/2 作为近似值,误差 ≤ eps

3. 最小真·最大假——四个黄金场景

3.1 场景 A:最小化最大值(典型题:路由器布点)

题干(缩编自 2024-09 五级真题)

给定 个村庄坐标 (升序)与路由器数量 ,问最小化相邻两路由器的最小距离,使全部安装完成。

单调性分析
  • • 若间距上限 可行(能布完个),则任意更大的间距≥也可行吗?
    反向:大间距更严格 →可行集合随 扩大呈单调不增
    因此:设check(d)判断“能否用间距 ≤ d 放满 k 个”;check先真后假,二分求最大 d 不可行或最小可行皆可。
判定函数
bool chekc(long long d){long long cnt = 1, prev = x[0];for(int i=1;i<n;++i)if(x[i] - prev >= d){++cnt; prev = x[i];}return cnt >= k;
}
二分主体
long long L = 0, R = x[n-1] - x[0];   // 答案区间
while(L < R){long long M = (L+R+1)>>1;         // 向上取整if(check(M)) L = M; else         R = M - 1;
}
cout << L;                            // 最大化最小间距

复杂度check O(n),外层 O(log R) ⇒ 总 O(n log R)。


3.2 场景 B:最小容量/速度/天数(船运包裹、打印机问题)

船运包裹(LeetCode 1011 同型,五级编程题改编)
  • • 输入重量数组 与期限 D;每天装一次船,容量 C;求最小 C
  • check(C):模拟装箱,若天数 ≤ D 返回 true
    单调:容量大不比小难装 → check 单调不降。

判定与二分(变量 ≤4 字母):

bool check(long long C){long long cur=0, day=1;for(int i=0; i<n; i++){if(w[i] > C) return 0;          // 单件超载if(cur + w[i] > C){day++; cur = 0; }cur += w[i];}return day <= D;
}
long long L=*max_element(w, w+n), R = 1e14;
while(L<R){long long M = L+(R-L)/2;if(check(M)) R = M;else         L = M + 1;
}

3.3 场景 C:计数型二分——第 小值

例:两排序数组第 k 小(变式)
  • • 目标:在整型域内找一个值 x,使 cnt(x) = A 中 ≤x + B 中 ≤x ≥ k。
    cnt(x)x 增大单调不减 ⇒ 二分最小 x 使 cnt(x)≥k

check 用两指针或双 upper_bound,复杂度 O(log n + log m)。


3.4 场景 D:实数逼近(牛顿冷却、几何距离)

例:求 (连续域)
double L=0, R=max(1.0,S);   // S≥0
for(int i = 0; i < 60; i++){double M = (L+R)/2;if(M*M >= S) R = M;else         L = M;
}
printf("%.8f\n",R);
  • • 迭代 60 次误差 ≤ 量级。
  • check(x) 直接比较平方 vs S

4. 模板总览

// 整数最小可行
long long bs_int(long long L, long long R){while(L < R){ longlong M = L+(R-L)/2;if(check(M)) R = M;else           L = M+1;}return L;
}// 整数最大不可行
long long bs_max(long long L, long long R){while(L < R){longlong M = L+(R-L+1)/2; // 上取整if(check(M)) L = M;else         R = M - 1;}return L;
}// 浮点最小可行(固定迭代)
double bs_flt(double L,double R){for(int i = 0; i < 100; i++){double M = (L+R)/2;if(check(M)) R = M;else         L = M;}return R;
}

5. 边界框定的四大技巧

  1. 1. 上界取极值:如船运题上界可设所有重量之和,安全但不失单调。
  2. 2. 下界取必需值:常用 max(单个元素最大值)或 0。
  3. 3. 指数放大:若未知上界,可先指数增大 R*=2 直到 check(R) 为真。
  4. 4. 防溢出:整型用 64 位;中点写 L + (R-L)/2

6. 常见陷阱 & Debug 步骤

陷阱

诊断

解决

死循环

日志发现 L==R-1 却无法合并

mid 取法是否向上/向下取整与更新语义配套

越界

返回值 = 上界+1

再判 check(ans);或补 if(!check(R)) 直接输出“无解”

check

非单调

样例随机打印 check(M-1)check(M),若同真同假则逻辑错

重新审题;必要时转量化顺序

浮点精度

输出 NaN 或无限循环

固定迭代次数、不要用 == 比较双精判断


7. GESP 真题剪影

  • 2023-12 单选 17:给 while(l<r){ mid=l+r>>1; if(chk(mid)) r=mid; else l=mid;} 问为何死循环?→ 少 +1
  • 2024-03 判断题:一句“在所有 check(x) 单调的情形下,二分答案复杂度一定是 。”答案判“√”。
  • 2024-09 编程大题:木板锯段求最大化最小长度,测试 ,log(1e9)≈30,轻松过时限。

8. 思维串联与比对

方法

适用

优点

缺点

枚举

任意

代码直观

可能超时

DP

可拆子结构

求最优值

状态设计复杂、空间大

二分答案

单调可判

、代码短

需保证单调;check 不能太慢

如果一题既满足单调又能写 判定,往往二分即“标程”。


9. 进一步拓展

  1. 1. 三分搜索:当目标函数先增后减(或先减后增)可用三分;连续极值定位。
  2. 2. 二分答案 + 贪心 / DScheck 内部再嵌贵贪心、并查集、线段树,例如 最大化最小差值 + Kruskal。
  3. 3. 双层二分:外层对答案,内层对辅助变量,如“最短总路程下最小速度”。

10. 总结与口诀

  • 单调 + 判定快 + 边界可给 ⇒ 果断二分答案。
  • 先假后真if(ok) R=M; else L=M+1先真后假 方向相反。
  • 整数向下取整用 M = L+(R-L)/2,向上取整加一
  • • 调试时在循环内输出 L,M,R 三值,肉眼观收缩情况。

牢牢记住这套“二分四步——判单调、定边界、写 check、套模板”。

三、分治算法初识

大纲把“将复杂问题拆分—递归—合并”列为五级算法入门核心;历届真题常以归并/快排选空、复杂度判断和递归代码补全呈现。


1. 概念两句话

  1. 1. Divide:把规模为 n 的任务切成若干更小的同类子任务;
  2. 2. Conquer & Combine:递归解决子任务后,将结果合并成整体答案。

只要拆分与合并耗时皆可写成递归式,便可用“主定理”在纸上秒得复杂度。


2. 典范一:归并排序 (Merge Sort)

2.1 思路
  • :把区间 [l,r] ⟶ 两半 [l,mid][mid+1,r]
  • :递归排序左右半段
  • :双指针归并成有序整段(线性)
2.2 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int a[N], tmp[N];void mrg(int l, int r){              // 归并排序 a[l..r]if(l >= r) return;int mid = (l+r)>>1;mrg(l, mid); mrg(mid+1, r);           // 递归int i = l, j = mid+1, k = l;              // 合并while(i <= mid && j <= r) tmp[k++] = (a[i] < a[j] ? a[i++] : a[j++]);while(i <= mid)   tmp[k++] = a[i++];while(j <= r)   tmp[k++] = a[j++];for(int t = l; t <= r; t++) a[t] = tmp[t];
}
2.3 复杂度

递归式 T(n)=2T(n/2)+Θ(n)T(n)=Θ(n log n);额外 Θ(n) 临时数组空间。

2.4 逆序对

归并排序可以统计逆序对的数量,a[j] > a[i] 的时候统计逆序对的数量 cnt += mid-i+1


3 典范二:快速排序 (Quick Sort)

3.1 思路
  • :随机选 pivot;一次扫描把数组分成 <p=p>p 三段
  • :递归排 <p>p
  • :拼接即可(无需额外线性操作)
3.2 代码(原地版)
int part(int l, int r){              // Hoare 分区int p = a[l+((r-l)>>1)];while(l <= r){while(a[l] < p) l++;while(a[r] > p) r--;if(l <= r) swap(a[l++], a[r--]);}return l;                       // 返回右段起点
}
void qks(int l, int r){if(l >= r) return;int m = part(l, r);qks(l, m-1);qks(m, r);
}
3.3 复杂度
  • 平均Θ(n log n)(均匀分割)
  • 最坏Θ(n²)(已排好或全相等且选坏 pivot)。
    真题往往让你在选择题里判断“平均”还是“最坏”!

4. 真题高频坑

  1. 1. 缺“合并”循环 —— 出现在 2024-03 单选填空:tmp[k++]=a[i++] 漏写导致数组错序。
  2. 2. 递归出口忘写 —— 导致栈溢出(l>=r 必写)。
  3. 3. 快排选择 pivot=arr[l] 对已排序列退化为 O(n²)。题干常问“应如何改进”?答:随机 pivot 或“三数取中”。
  4. 4. 空间复杂度 归并 Θ(n),快排原地 Θ(1)。判断题考过。

5. 练习

  1. 1. 填空:补齐归并排序中的合并指针循环。
  2. 2. 选择:给四个递归式,选与归并排序相同复杂度的。
  3. 3. 编程:随机生成 n (≤ 2 × 10⁵) 整数,用快排输出升序(要求变量≤4字母)。
  4. 4. 判断:快排平均时间是 O(n log n)。(√)


 


 

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

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

相关文章

程序猿成长之路之数据挖掘篇——聚类算法介绍

作为无监督学习算法的基础&#xff0c;学好聚类算法很关键&#xff0c;我之前介绍过kmeans聚类算法&#xff0c;现在系统的介绍一下聚类算法 1. 什么是分类 日常生活中我们会经常见到分类的情况&#xff0c;如家里大扫除时给物品归类&#xff0c;超市货架上商品分类等。分类就…

PostgreSQL 性能优化与集群部署:PGCE 认证培训实战指南

&#xff5c;深夜被数据库报警惊醒&#xff1f; &#xff5c;海量数据查询卡死业务&#xff1f; &#xff5c;主库宕机导致服务中断&#xff1f; 如果你正被这些PostgreSQL生产难题困扰&#xff0c;是时候系统掌握数据库内核优化与高可用架构了&#xff01;深度求索联合PG分会…

Java 对象映射 数据库表映射 工具类 两个对象/表实现映射转换

场景&#xff1a;需要将一个对象的各个字段中的数据映射到另一个对象的字段数据中&#xff0c;或将一个数据库表映射到另一张表中。 本文使用泛型编程实现了一个对象映射功能的工具类。 需要源对象&#xff0c;映射关系map&#xff0c;目标类。由于是动态的类&#xff0c;所以…

Linux离线搭建Jenkins

Linux离线搭建Jenkins(centos7) Jenkins简介: Jenkins只是一个平台&#xff0c;真正运作的都是插件。这就是jenkins流行的原因&#xff0c;因为jenkins什么插件都有&#xff0c;Hudson是Jenkins的前身&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控程序重…

从零学习linux(2)——管理

一.用户管理 1.用户属性 用户名、口令、用户ID&#xff08;UID&#xff09;、用户主目录&#xff08;HOME&#xff09;、用户shell 2. 3. 4.adduser添加用户 语法&#xff1a;adduser 用户名 如# adduser superw 添加用户名为superw的新用户 5.deluser删除用户 语法&am…

《贵州棒垒球》有什么国家级比赛·棒球1号位

中国国家级棒球比赛盘点 | 小白入门指南 3月 | 中国棒球联赛 (China Baseball League) 国内最高水平职业联赛&#xff0c;各省市职业队角逐冠军&#xff01; 英文&#xff1a;Top-tier professional event with teams nationwide. 5月 | 全国青年棒球锦标赛 (National Youth …

该项目名为“EduPal“,AI推荐

## 完整代码实现 ### 后端代码 (app.py) python import os import json import uuid import requests from datetime import datetime from flask import Flask, render_template, request, jsonify from dotenv import load_dotenv # 加载环境变量 load_dotenv() app …

C++法则15:匹配失败并不是一种错误(Substitution Failure Is Not An Error)。

C法则15&#xff1a;匹配失败并不是一种错误(Substitution Failure Is Not An Error)。 应用例子&#xff1a; SFINAE &#xff1a;关于is_class&#xff0c;is_base_of&#xff0c;C编译器的魔法器&#xff0c;如何实现&#xff0c;is_class&#xff0c;is_base_of。_c is cl…

Ollama客户端 + Docker搭建本地知识库(Mac系统)

一、环境准备 1. 安装Ollama客户端 官网下载&#xff1a;https://ollama.com 验证安装&#xff1a; ollama --version2. 安装Docker Desktop 下载地址&#xff1a;https://www.docker.com/products/docker-desktop 安装后确保Docker状态为"Running" 二、基础搭建…

FastMCP 2.9 版本详解:MCP 原生中间件与类型转换增强

下面我将从三个方面来讲解这个&#xff0c;第一是讲解2.9版本的更新&#xff0c;第二是讲解什么将手动解析底层JSON-RPC 消息&#xff0c;丢失 FastMCP 高层语义&#xff0c;第三是讲一讲&#xff0c;什么叫做中间件。不了解的兄弟们系好安全带&#xff0c;我们准备发车了&…

LTspice仿真6——PWL折线波产生

1.自定义波形 2.自定义波形周期 3.以文件.txt的形式定义折线波 4.通过C语言编程&#xff0c;一系列操作&#xff0c;生成自定义正弦波&#xff08;可自定义性强&#xff09;

FunASR搭建语音识别服务和VAD检测

调整VAD参数 1. 查找VAD模型的配置文件 FunASR中的VAD模型为FSMN-VAD&#xff0c;参数配置类为VADXOptions&#xff0c;可以在以下路径中找到&#xff1a; /workspace/FunASR/runtime/python/onnxruntime/funasr_onnx/utils/e2e_vad.py 其中&#xff0c;VADXOptions类定义了…

多模态大模型(从0到1)

文章目录 一、多模态大模型二、常见模态组合 典型应用场景三、多模态&#xff08;模型 框架&#xff09;1. 多模态模型2. 多模态框架 —— 开源项目推荐&#xff08;可快速上手&#xff09; 四、入门与学习路线1. 理论基础2. 主流多模态模型实战3. 进阶与应用拓展&#x1f4d…

# Vue.js 精确轮播组件实现详解

## &#x1f4d6; 概述 本文详细介绍了一个基于 Vue.js 开发的高精度轮播组件&#xff0c;该组件实现了精确的卡片对齐和平滑滚动效果。组件支持混合布局&#xff08;大卡片网格布局&#xff09;&#xff0c;具备智能位置计算和精确滚动控制功能。 ## ✨ 组件特点 ### &#x1…

将RESP.app的备份数据转码成AnotherRedisDesktopManager的格式

将RESP.app的备份数据转码成AnotherRedisDesktopManager的格式 最近发现了AnotherRedisDesktopManager&#xff0c;这个软件可以直接展示proto数据。 将RESP.app导出的json文件&#xff0c;转码为AnotherRedisDesktopManager的ano文件&#xff08;是一个list转了base64&#xf…

前端基础知识JavaScript系列 - 09(JavaScript原型,原型链 )

一、原型 JavaScript 常被描述为一种基于原型的语言——每个对象拥有一个原型对象 当试图访问一个对象的属性时&#xff0c;它不仅仅在该对象上搜寻&#xff0c;还会搜寻该对象的原型&#xff0c;以及该对象的原型的原型&#xff0c;依次层层向上搜索&#xff0c;直到找到一个…

vue3+ts 使用VueCropper实现剪切图片

效果图&#xff1a; 参考文档&#xff1a; Vue-Cropper 文档Vue-Cropper 文档 安装VueCropper //npm安装 npm install vue-croppernext -d --save//yarn安装 yarn add vue-croppernext 引入组件 在main.ts中全局注册&#xff1a; import VueCropper from vue-cropper; i…

el-table特殊表头样式

el-table特殊表头样式 实现表头是按钮 <el-table-column align"center"><template slot"header"><el-buttonsize"mini"type"primary"icon"el-icon-plus"circleclick"addData"></el-button&g…

el-tree的属性render-content自定义样式不生效

需求是想要自定义展示el-tree的项&#xff0c;官网有一个:render-content属性&#xff0c;用的时候发现不管是使用class还是style&#xff0c;样式都没有生效&#xff0c;还会报一个错&#xff0c;怎么个事呢&#xff0c;后来发现控制台还会报一个错“vue.js:5129 [Vue warn]: …

银杏书签里的春天

春末的细雨沾湿了旧书扉页&#xff0c;我在泛黄的《飞鸟集》里发现那枚银杏书签时&#xff0c;窗外的梧桐树正抖落最后一片枯叶。深褐色的叶脉间夹着张字条&#xff0c;娟秀的字迹被岁月晕染&#xff1a;"给永远在奔跑的人。" 十年前的我在旧书店打工&#xff0c;每天…