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

数列分块入门

本期是数列分块入门。其中的大部分题目来自hzwer在LOJ上提供的数列分块入门系列。

Blog:here  (其实是对之前分块的 blog 的整理补充)     sto   hzwer   orz     %%%            [转载]

------------------------------------------------------------------------------------------------------------------------

分块

我举个例子来说分块。

在一个学校里,有很多班级,而每一个班级就是一个块。

假设某天校长想知道一个班考试的总分,直接查询即可。那如果要查询 1 班的 30 号到 10 班的 20 号呢?对于完整的班级,直接查询;不完整的暴力。

那什么时候这个算法时间复杂度最低呢?答:当块的长度为\sqrt n时。

而这就是分块。

例题

LOJ-P6277:

我们每m个元素个元素分为一块,共有\frac{n}{m}块,以及区间两侧的两个不完整的块。这两个不完整的块中至多2m个元素。我们给每个块设置一个tag(就是记录这个块中元素一起加了多少),每次操作对每个整块直接\Theta (1)标记,而不完整的块元素较少,暴力修改元素的值。

这样,每次询问时返回元素的值加上其所在块的加法标记即可。

时间复杂度\Theta (\frac{n}{m})+\Theta (m)。根据均值不等式,当m\sqrt{n}时总复杂度最低。

#include <bits/stdc++.h>
using namespace std;
const int maxn=50005;
int a[maxn],idx[maxn],tag[maxn],tot;
void change(int l,int r,int c){for(int i=l;i<=min(idx[l]*tot,r);i++)a[i]+=c;if(idx[l]!=idx[r]){for(int i=(idx[r]-1)*tot+1;i<=r;i++)a[i]+=c;}for(int i=idx[l]+1;i<=idx[r]-1;i++)tag[i]+=c;
}
int main(){int n;cin>>n;tot=sqrt(n);for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++)idx[i]=(i-1)/tot+1;for(int i=1;i<=n;i++){int opt,l,r,c;cin>>opt>>l>>r>>c;if(opt==0)change(l,r,c);if(opt==1)cout<<a[r]+tag[idx[r]]<<endl;}return O;
}

LOJ-P6278:

我们先来思考只有询问操作的情况,不完整的块枚举统计即可;而要在每个整块内寻找小于一个值的元素数,于是我们不得不要求块内元素是有序的,这样就能使用二分法对块内查询,需要预处理时每块做一遍排序,复杂度\Theta (n\: log\: n),每次查询在\sqrt{n}个块内二分,以及暴力2 \sqrt{n}个元素,总复杂度\Theta (n\: log\: n+n\sqrt{n}\:\: log\: \sqrt{n})

那么区间加怎么办呢?套用第一题的方法,维护一个加法标记,略有区别的地方在于,不完整的块修改后可能会使得该块内数字乱序,所以头尾两个不完整块需要重新排序。在加法标记下的询问操作,块外还是暴力,查询小于(x-tag)的元素个数,块内用(x-tag)作为二分的值即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn=50005;
int a[maxn],idx[maxn],tag[maxn],tot,n;
vector<int> block[505];
void reset(int x){block[x].clear();for(int i=(x-1)*tot+1;i<=min(x*tot,n);i++)block[x].push_back(a[i]);sort(block[x].begin(),block[x].end());
}
void change(int l,int r,int c){for(int i=l;i<=min(idx[l]*tot,r);i++)a[i]+=c;reset(idx[l]);if(idx[l]!=idx[r]){for(int i=(idx[r]-1)*tot+1;i<=r;i++)a[i]+=c;reset(idx[r]);}for(int i=idx[l]+1;i<=idx[r]-1;i++)tag[i]+=c;
}
int query(int l,int r,int c){int ans=0;for(int i=l;i<=min(idx[l]*tot,r);i++){if(a[i]+tag[idx[l]]<c)ans++;}if(idx[l]!=idx[r]){for(int i=(idx[r]-1)*tot+1;i<=r;i++){if(a[i]+tag[idx[r]]<c)ans++;}}for(int i=idx[l]+1;i<=idx[r]-1;i++)ans+=lower_bound(block[i].begin(),block[i].end(),c-tag[i])-block[i].begin();return ans;
}
int main(){cin>>n;tot=sqrt(n);for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++){idx[i]=(i-1)/tot+1;block[idx[i]].push_back(a[i]);}for(int i=1;i<=idx[n];i++)sort(block[i].begin(),block[i].end());for(int i=1;i<=n;i++){int opt,l,r,c;cin>>opt>>l>>r>>c;if(opt==0)change(l,r,c);if(opt==1)cout<<query(l,r,c*c)<<endl;}return O;
}

LOJ-P6279:

接着第二题的解法,其实只要把块内查询的二分稍作修改即可。

不过这题其实想表达:可以在块内维护其它结构使其更具有拓展性,比如放一个set,这样如果还有插入、删除元素的操作,会更加的方便。

#include <bits/stdc++.h>
using namespace std;
const int maxn=10000S;
int a[maxn],idx[maxn],tag[maxn],tot=1000;
set<int> st[10S];
void change(int l,int r,int c){for(int i=l;i<=min(idx[l]*tot,r);i++){st[idx[l]].erase(a[i]);a[i]+=c;st[idx[l]].insert(a[i]);}if(idx[l]!=idx[r]){for(int i=(idx[r]-1)*tot+1;i<=r;i++){st[idx[r]].erase(a[i]);a[i]+=c;st[idx[r]].insert(a[i]);}}for(int i=idx[l]+1;i<=idx[r]-1;i++)tag[i]+=c;
}
int query(int l,int r,int c){int ans=-1;for(int i=l;i<=min(idx[l]*tot,r);i++){int val=a[i]+tag[idx[l]];if(val<c)ans=max(val,ans);}if(idx[l]!=idx[r]){     for(int i=(idx[r]-1)*tot+1;i<=r;i++){int val=a[i]+tag[idx[r]];if(val<c)ans=max(val,ans);}}for(int i=idx[l]+1;i<=idx[r]-1;i++){int x=c-tag[i];set<int>::iterator itr=st[i].lower_bound(x);if(itr==st[i].begin())continue;--itr;ans=max(ans,*itr+tag[i]);}return ans;
}
int main(){int n;cin>>n;for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++){idx[i]=(i-1)/tot+1;st[idx[i]].insert(a[i]);}for(int i=1;i<=n;i++){int opt,l,r,c;cin>>opt>>l>>r>>c;if(opt==0)change(l,r,c);if(opt==1)cout<<query(l,r,c)<<endl;}return 0;
}

LOJ-P6280:

这题的询问变成了区间上的询问,不完整的块还是暴力;而要想快速统计完整块的答案,需要维护每个块的元素和,先要预处理一下。

考虑区间修改操作,不完整的块直接改,顺便更新块的元素和;完整的块类似之前标记的做法,直接根据块的元素和所加的值计算元素和的增量。

#include <bits/stdc++.h>
using namespace std;
int idx[50005],tot;
long long a[50005],tag[50005],sum[50005];
void change(int l,int r,int c){for(int i=l;i<=min(idx[l]*tot,r);i++){a[i]+=c;sum[idx[l]]+=c;}if(idx[l]!=idx[r]){for(int i=(idx[r]-1)*tot+1;i<=r;i++){a[i]+=c;sum[idx[r]]+=c;}}for(int i=idx[l]+1;i<=idx[r]-1;i++)tag[i]+=c;
}
long long query(int l,int r){long long ans=0;for(int i=l;i<=min(idx[l]*tot,r);i++)ans+=a[i]+tag[idx[l]];if(idx[l]!=idx[r]){for(int i=(idx[r]-1)*tot+1;i<=r;i++)ans+=a[i]+tag[idx[r]];}for(int i=idx[l]+1;i<=idx[r]-1;i++)ans+=sum[i]+tot*tag[i];return ans;
}
int main(){int n;cin>>n;tot=sqrt(n);for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++){idx[i]=(i-1)/tot+1;sum[idx[i]]+=a[i];}for(int i=1;i<=n;i++){int opt,l,r,c;cin>>opt>>l>>r>>c; if(opt==O)change(l,r,c);if(opt==1)cout<<query(l,r)%(c+1)<<endl;}return 0;
}

LOJ-P6281:

稍作思考可以发现,开方操作比较棘手,主要是对于整块开方时,必须要知道每一个元素,才能知道他们开方后的和,也就是说,难以快速对一个块信息进行更新。

看来我们要另辟蹊径。不难发现,这题的修改就只有下取整开方,而一个数经过几次开方之后,它的值就会变成0或者1

如果每次区间开方只不涉及完整的块,意味着不超过2\sqrt{n}个元素,直接暴力即可。

如果涉及了一些完整的块,这些块经过几次操作以后就会都变成01,于是我们采取一种分块优化的暴力做法,只要每个整块暴力开方后,记录一下元素是否都变成了01,区间修改时跳过那些全为01的块即可。

这样每个元素至多被开方不超过4次,显然复杂度没有问题。

#include <bits/stdc++.h> 
using namespace std;
int a[50005],sum[50005],idx[50005],tot;
bool flag[50005];
void solve(int x){if(flag[x])return;flag[x]=1;sum[x]=0;for(int i=(x-1)*tot+1;i<=x*tot;i++){a[i]=sqrt(a[i]);sum[x]+=a[i];if(a[i]>1)flag[x]=0;}
}
void change(int l,int r,int c){for(int i=l;i<=min(idx[l]*tot,r);i++){sum[idx[l]]-=a[i];a[i]=sqrt(a[i]);sum[idx[l]]+=a[i];}if(idx[l]!=idx[r]){for(int i=(idx[r]-1)*tot+1;i<=r;i++){sum[idx[r]]-=a[i];a[i]=sqrt(a[i]);sum[idx[r]]+=a[i];}}for(int i=idx[l]+1;i<=idx[r]-1;i++)solve(i);
}
int query(int l,int r){int ans=0;for(int i=l;i<=min(idx[l]*tot,r);i++)ans+=a[i];if(idx[l]!=idx[r]){for(int i=(idx[r]-1)*tot+1;i<=r;i++)ans+=a[i];}for(int i=idx[l]+1;i<=idx[r]-1;i++)ans+=sum[i];return ans;
}
int main(){int n;cin>>n;tot=sqrt(n);for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++){idx[i]=(i-1)/tot+1;sum[idx[i]]+=a[i];}for(int i=1;i<=n;i++){int opt,l,r,c;cin>>opt>>l>>r>>c;if(opt==0)change(l,r,c);if(opt==l)cout<<query(l,r)<<endl;}return 0;
}

LOJ-P6284:

区间修改没有什么难度,这题难在区间查询比较奇怪,因为权值种类比较多,似乎没有什么好的维护方法。

模拟一些数据可以发现,询问后一整段都会被修改,几次询问后数列可能只剩下几段不同的区间了。

我们思考这样一个暴力,还是分块,维护每个分块是否只有一种权值,区间操作的时候,对于同权值的一个块就\Theta(1)统计答案,否则暴力统计答案,并修改标记,不完整的块也暴力。

这样看似最差情况每次都会耗费\Theta(n)的时间,但其实可以这样分析:

假设初始序列都是同一个值,那么查询是\Theta(\sqrt n),如果这时进行一个区间操作,它最多破坏首尾2个块的标记,所以只能使后面的询问至多多2个块的暴力时间,所以均摊每次操作复杂度还是\Theta(\sqrt{n})。换句话说,要想让一个操作耗费\Theta(n)的时间,要先花费\sqrt{n}个操作对数列进行修改。初始序列不同值,经过类似分析后,就可以放心的暴力啦。

#include <bits/stdc++.h>
using namespace std;
int a[maxn],block[maxn],tag[maxn],n,s;
void reset(int x){if(tag[x]==-1)return;for(int i=(x-1)*s+1;i<=s*x;i++)a[i]=tag[x];tag[x]=-1;
}
int query(int l,int r,int c){    int ans=0;reset(block[l]);for(int i=l;i<=min(block[l]*s,r);i++){if(a[i]!=c)a[i]=c;elseans++;}if(block[l]!=block[r]){reset(block[r]);for(int i=(block[r]-1)*s+1;i<=r;i++){if(a[i]!=c)a[i]=c;elseans++;}}for(int i=block[l]+1;i<=block[r]-1;i++){if(tag[i]!=-1){if(tag[i]!=c)tag[i]=c;elseans+=s;}else{for(int j=(i-1)*s+1;j<=i*s;j++){if(a[j]!=c)a[j]=c;elseans++;}tag[i]=c;}}return ans;
}
int main(){memset(tag,-1,sizeof(tag));int n;cin>>n;s=sqrt(n);for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++)block[i]=(i-1)/s+1;for(int i=1;i<=n;i++){int l,r,c;cin>>l>>r>>c;cout<<query(l,r,c)<<endl;}return 0;
}

HDU 5057:

分块板题。

#include <bits/stdc++.h>
using namespace std;
const int maxn=100005;
int v[maxn][15],tag[320][15][15],a[maxn];
void update(int x,int y,int z){for(int d=1;d<=10;d++){v[x][d]=y%10;tag[x/S][d][y%10]+=z;y/=10;}
}
int query(int l,int r,int d,int p){int L=l/S,R=r/S,res=0;if(L==R){for(int i=l;i<=r;i++)res+=(v[i][d]==p);}else{for(int i=l;i<(L+1)*S;i++)res+=(v[i][d]==p);for(int i=R*S;i<=r;i++)res+=(v[i][d]==p);for(int i=L+1;i<R;i++)res+=tag[i][d][p];}return res;
}
int main(){int t;cin>>t;while(t--){memset(tag,0,sizeof(tag));memset(v,0,sizeof(v));int n,m;cin>>n>>m;S=sqrt(n);for(int i=1;i<=n;i++){cin>>a[i];update(i,a[i],1);}while(m--){char op;cin>>op;if(op=='S'){int x,y;cin>>x>>y;update(x,a[x],-1);update(x,y,1);a[x]=y;}else{int l,r,d,p;cin>>l>>r>>d>>p;cout<<query(l,r,d,p)<<endl;}}}return 0;
}

友情提醒:不要Ctrl C+Ctrl V

相关文章:

数列分块入门

本期是数列分块入门。其中的大部分题目来自hzwer在LOJ上提供的数列分块入门系列。 Blog:here (其实是对之前分块的 blog 的整理补充) sto hzwer orz %%% [转载] ---------------------------------------------------------------------------------…...

SPRD Android 14 Launcher 3 中添加长按桌面图标启动自由窗口模式功能

本文将介绍如何在SPRD Android 14 Launcher 3 中实现一个功能,使用户可以通过长按应用图标来启动自由窗口模式。这一功能的实现将提升多任务处理能力和应用使用体验。 修改的文件列表 以下是主要涉及的文件及其修改内容: QuickstepLauncher.java:添加自由窗口快捷方式的支…...

WebSocket详解:从前端到后端的全栈理解

文章目录 前言一、WebSocket简介1.1 WebSocket的特点 二、WebSocket的工作原理2.1 握手过程2.2 数据传输 三、WebSocket在前端的应用四、WebSocket在后端的应用五、WebSocket的局限与解决方案结语 前言 随着互联网技术的发展&#xff0c;传统的HTTP协议在某些场景下的局限性逐…...

SOLIDWORKS 2025加快装配体设计 确保可制造性

在快速变化的制造业环境中&#xff0c;SOLIDWORKS作为一款CAD软件&#xff0c;始终致力于提供有效、智能且可靠的解决方案&#xff0c;以满足设计师和工程师对装配体设计的多样化需求。随着SOLIDWORKS 2025版本的发布&#xff0c;其在加快装配体设计、确保可制造性方面取得了显…...

简单题:计算从位置 x 到 y 的最少步数| 豆包MarsCode AI刷题

题目解析&#xff1a;计算从位置 x 到 y 的最少步数 题目描述 题目要求从整数位置 x 移动到整数位置 y&#xff0c;每一步可以将当前位置增加或减少&#xff0c;且每步的增加或减少的值必须是连续的整数。首末两步的步长必须是 1。要求求出从 x 到 y 的最少步数。 思路分析 …...

HTML 基础标签——表单标签<form>

文章目录 1. `<form>` 标签:定义表单容器2. `<input>` 标签:多用途输入控件3. `<textarea>` 标签:多行文本输入框4. `<select>` 标签:下拉选择框5. `<option>` 标签:下拉菜单选项6. `<button>` 标签:按钮元素7. `<label>` 标签…...

LeetCode 每日一题 2024/10/28-2024/11/3

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 10/28 685. 冗余连接 II10/29 3211. 生成不含相邻零的二进制字符串10/30 3216. 交换后字典序最小的字符串10/31 3165. 不包含相邻元素的子序列的最大和11/1 3259. 超级饮料…...

基于Spring Boot和Vue的电子商城系统功能设计

基于Spring Boot和Vue的电子商城系统功能设计 该系统是一个基于Spring Boot和Vue框架的电子商城平台&#xff0c;包含前台商城和后台管理系统。系统功能设计包括用户购物体验和管理员管理功能&#xff0c;支持商品的分类展示、收藏、购物车和订单管理等模块。以下是系统功能的简…...

成都睿明智科技有限公司正规吗靠谱吗?

在这个短视频风起云涌的时代&#xff0c;抖音电商以其独特的魅力&#xff0c;成为了无数商家竞相追逐的新蓝海。而在这片浩瀚的商海中&#xff0c;成都睿明智科技有限公司犹如一艘装备精良的航船&#xff0c;引领着众多企业破浪前行&#xff0c;探索抖音电商的无限可能。今天&a…...

【天线&化学】航拍图屋顶异常检测系统源码&数据集全套:改进yolo11-ContextGuided

改进yolo11-ContextGuided等200全套创新点大全&#xff1a;航拍图屋顶异常检测系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.11.01 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示”展示的系…...

【回忆】JavaScript 中的 Map 有哪些方法

在 JavaScript 中&#xff0c;Map 对象是一种键值对的集合&#xff0c;类似于对象&#xff0c;但“键”可以是任何数据类型&#xff08;对象或原始值&#xff09;。Map 提供了多种方法来操作这些键值对。以下是 Map 对象的一些常用方法&#xff1a; 创建和初始化 new Map(): …...

Chrome与夸克的安全性对比

在当今数字化时代&#xff0c;浏览器的安全性对于用户来说至关重要。Chrome和夸克作为两款流行的浏览器&#xff0c;各有其特点和优势。本文将对这两款浏览器的安全性进行详细对比&#xff0c;帮助用户更好地了解它们之间的差异。&#xff08;本文由https://www.chromegw.com/的…...

使用Python可视化支持向量机(SVM)

支持向量机&#xff08;SVM&#xff09;是用于分类和回归任务的强大监督学习模型。它们受欢迎背后的一个关键因素是它们有效处理线性和非线性数据的能力。在本文中&#xff0c;我们将探索使用Python和流行的库&#xff08;如scikit-learn和Matplotlib&#xff09;可视化SVM。 …...

C++泛型编程

一、什么是泛型编程 泛型编程 是一种编程范式&#xff0c;它通过编写可以处理多种数据类型的代码来实现代码的灵活复用。泛型编程主要通过模板来实现。 比如我们日常使用的容器类型vector就应用了模板来实现其通用性&#xff0c;我们在使用时可以通过传入型别创建对应的动态数…...

【论文分享】利用大量街景图片研究街道空间质量与建筑环境属性之间的关联

本研究通过有序逻辑回归模型&#xff0c;结合街景图片和街道数据&#xff0c;分析了街道空间质量与建筑环境属性的关系。通过Kappa分析和相关性分析&#xff0c;确定了影响街道空间质量的因素&#xff0c;并绘制了质量分布图。这些因素与街道质量的不同维度相关联&#xff0c;对…...

【Linux第七课--基础IO】内存级文件、重定向、缓冲区、文件系统、动态库静态库

目录 引入内存级文件重新使用C文件接口 -- 对比重定向写文件读文件文件流 认识文件操作的系统接口open参数 -- flagflag的内容宏的传参方式 open关闭文件写文件读文件结论 引入文件描述符fd、对文件的理解理解一切皆文件方法集文件fd的分配规则 重定向代码的重定向输入重定向输…...

对比C/C++语言,Rust语言有什么优势?

Rust语言相较于C/C语言有以下几个主要优势&#xff1a; 1. 内存安全&#xff1a;Rust通过其所有权系统和借用规则在编译时捕获许多常见的内存安全错误&#xff0c;如空指针引用和数据竞争&#xff0c;避免了许多常见的安全漏洞。这与C/C不同&#xff0c;后者通常需要手动管理内…...

Rust语言有哪些数据类型?

Rust语言的数据类型主要包括以下几种&#xff1a; 一、基本数据类型 1. 整数类型 i8, i16, i32, i64, i128: 有符号整数 u8, u16, u32, u64, u128: 无符号整数 isize, usize: 根据平台选择大小的整数&#xff08;通常用于指针和索引&#xff09; 2. 浮点数类型 f32: 32位浮…...

【论文笔记】Attention Prompting on Image for Large Vision-Language Models

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Attention Prompting on I…...

VScode设置系统界面字体

现象&#xff1a; 系统界面字体太大&#xff0c;导致菜单栏字体显示不全&#xff0c;每次使用都要先点然后才能打开终端和帮助 缩小字体应该就可以实现全部都看到的效果 步骤 Window: Zoom Level 调整所有窗口的默认缩放级别。大于“0”的每个增量&#xff08;例如“1”&…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...