严格根号带修 RMQ
其实很简单,把之前随机数据的解法中维护块内数据的数据结构换成约束 RMQ,这样子复杂度 严格 单点修改 \(O(\sqrt n)\),区间查询 \(O(1)\),线性空间。
唯一的问题是常数太大了,有 \(4\) 倍常数。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2000;
const int MAXM = 20;
const int warma = 1000;
int a[1000001];
int INPUT[MAXN];
int cnt;
struct RMQ {
int mx;
int N, A[MAXN];
int blockSize;
int S[MAXN][MAXM], Pow[MAXM], Log[MAXN];
int Belong[MAXN], Pos[MAXN];
int Pre[MAXN], Sub[MAXN];
int F[MAXN];
void buildST() {
int cur = 0, id = 1;
Pos[0] = -1;
for (int i = 1; i <= N; ++i) {
S[id][0] = std::max(S[id][0], A[i]);
Belong[i] = id;
if (Belong[i - 1] != Belong[i])
Pos[i] = 0;
else
Pos[i] = Pos[i - 1] + 1;
if (++cur == blockSize) {
cur = 0;
++id;
}
}
if (N % blockSize == 0) --id;
Pow[0] = 1;
for (int i = 1; i < MAXM; ++i) Pow[i] = Pow[i - 1] * 2;
for (int i = 2; i <= id; ++i) Log[i] = Log[i / 2] + 1;
for (int i = 1; i <= Log[id]; ++i) {
for (int j = 1; j + Pow[i] - 1 <= id; ++j) {
S[j][i] = std::max(S[j][i - 1], S[j + Pow[i - 1]][i - 1]);
}
}
}
void buildSubPre() {
for (int i = 1; i <= N; ++i) {
if (Belong[i] != Belong[i - 1])
Pre[i] = A[i];
else
Pre[i] = std::max(Pre[i - 1], A[i]);
}
for (int i = N; i >= 1; --i) {
if (Belong[i] != Belong[i + 1])
Sub[i] = A[i];
else
Sub[i] = std::max(Sub[i + 1], A[i]);
}
}
void buildBlock() {
static int S[MAXN], top;
for (int i = 1; i <= N; ++i) {
if (Belong[i] != Belong[i - 1])
top = 0;
else
F[i] = F[i - 1];
while (top > 0 && A[S[top]] <= A[i]) F[i] &= ~(1 << Pos[S[top--]]);
S[++top] = i;
F[i] |= (1 << Pos[i]);
}
}
void init() {
for(int i=1;i<=1001;i++){
A[i]=Log[i]=Belong[i]=Pos[i]=Pre[i]=Sub[i]=F[i]=0;
}
for(int i=1;i<=20;i++){
Pow[i]=0;
}
for(int i=1;i<=101;i++){
for(int j=1;j<=11;j++){
S[i][j]=0;
}
}
mx=0;
for (int i = 1; i <= N; ++i) A[i]=INPUT[i],mx=max(mx,A[i]);
blockSize = max( (int)(log2(N) * 1.5),1);
buildST();
buildSubPre();
buildBlock();
}
int queryMax(int l, int r) {
int bl = Belong[l], br = Belong[r];
if (bl != br) {
int ans1 = 0;
if (br - bl > 1) {
int p = Log[br - bl - 1];
ans1 = std::max(S[bl + 1][p], S[br - Pow[p]][p]);
}
int ans2 = std::max(Sub[l], Pre[r]);
return std::max(ans1, ans2);
} else {
return A[l + __builtin_ctz(F[r] >> Pos[l])];
}
}
} R[MAXN];
void init(){
for(int i=1;i<=cnt;i++){
INPUT[i]=R[i].mx;
}
R[cnt+1].N=cnt;
R[cnt+1].init();
}
int query(int l,int r){
int bl=l/warma+1;
l%=warma;
if(l==0){
bl--;
l+=warma;
}
int br=r/warma+1;
r%=warma;
if(r==0){
br--;
r+=warma;
}
if(bl==br){
return R[bl].queryMax(l,r);
}
else if(bl+1==br){
return max(R[bl].queryMax(l,R[bl].N),R[br].queryMax(1,r));
}
else{
return max(max(R[bl].queryMax(l,R[bl].N),R[br].queryMax(1,r)),R[cnt+1].queryMax(bl+1,br-1));
}
}
void add(int pos,int val){
a[pos]+=val;
int bpos=pos/warma+1;
if(pos%warma==0){
bpos--;
}
int len=0;
for(int i=(bpos-1)*warma+1;i<=min(n,bpos*warma);i++){
len++;
INPUT[i-(bpos-1)*warma]=a[i];
}
R[bpos].N=len;
R[bpos].init();
init();
}
int n,m;
int last=1;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
if(i%warma==0){
R[++cnt].N=(i-last+1);
for(int j=last;j<=i;j++){
INPUT[j-last+1]=a[j];
}
R[cnt].init();
last=i+1;
}
}
if(last<=n){
R[++cnt].N=(n-last+1);
for(int j=last;j<=n;j++){
INPUT[j-last+1]=a[j];
}
R[cnt].init();
last=n+1;
}
init();
while(m--){
int l,r;
cin>>l>>r;
cout<<query(l,r)<<'\n';
}
/*
scanf("%d%d", &R.N, &M);
R.init();
for (int i = 0, l, r; i < M; ++i) {
scanf("%d%d", &l, &r);
printf("%d\n", R.queryMax(l, r));
}
*/
return 0;
}
严格根号带修 RMQ的更多相关文章
- Codeforces 1476G - Minimum Difference(带修莫队+根号平衡)
Codeforces 题目传送门 & 洛谷题目传送门 震惊!我竟然独立切掉了这道 *3100 的题! 虽然此题难度的确虚高,感觉真实评分也就 2800~2900 罢.但感觉还是挺有成就感的( ...
- 莫队初探(不带修/例题极少)By cellur925
因为今天考到莫队裸题了嘤嘤嘤...而我这样的蒟蒻肯定不会这样的高端算法啊QAQ.于是暴力水了40分qwq. 正如上文所说,我实在太菜了,于是学习莫队也只是学习了最简单的不带修普通莫队,如果我能苟到省选 ...
- 【BZOJ-1146】网络管理Network DFS序 + 带修主席树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3495 Solved: 1032[Submi ...
- 【BZOJ-3052】糖果公园 树上带修莫队算法
3052: [wc2013]糖果公园 Time Limit: 200 Sec Memory Limit: 512 MBSubmit: 883 Solved: 419[Submit][Status] ...
- 主席树套树状数组——带修区间第k大zoj2112
主席树带修第k大 https://www.cnblogs.com/Empress/p/4659824.html 讲的非常好的博客 首先按静态第k大建立起一组权值线段树(主席树) 然后现在要将第i个值从 ...
- 「洛谷1903」「BZOJ2120」「国家集训队」数颜色【带修莫队,树套树】
题目链接 [BZOJ传送门] [洛谷传送门] 题目大意 单点修改,区间查询有多少种数字. 解法1--树套树 可以直接暴力树套树,我比较懒,不想写. 稍微口胡一下,可以直接来一个树状数组套主席树,也就是 ...
- BZOJ2120 数颜色 莫队 带修莫队
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2120.html 题目传送门 - BZOJ2120 题意 给定一个长度为 $n$ 的序列 $a$ ,有 ...
- BZOJ3052/UOJ#58 [wc2013]糖果公园 莫队 带修莫队 树上莫队
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3052.html 题目传送门 - BZOJ3052 题目传送门 - UOJ#58 题意 给定一棵树,有 ...
- UVA 12345 Dynamic len(带修莫队)
Dynamic len [题目链接]Dynamic len [题目类型]带修莫队 &题解: 莫队可以单点更改,只要再多加一维,代表查询次数,排序的时候3个关键字. 之后循环离线的时候,先暴力时 ...
- bzoj 2120 数颜色 (带修莫队)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2120 题意:两种操作:Q 询问区间 l - r 内颜色的种类 ,R 单点修改 思路 ...
随机推荐
- 深度学习框架火焰图pprof和CUDA Nsys配置指南
注:如下是在做深度学习框架开发时,用到的火焰图pprof和 CUDA Nsys 配置指南,可能对大家有一些帮助,就此分享.一些是基于飞桨的Docker镜像配置的. 一.环境 & 工具配置 0. ...
- keepalived(2)- keepalived安装和配置
目录 1. keepalived安装配置 1.1 keepalived安装环境 1.2 keepalived日志文件 1.3 keepalived配置文件 2. keepalived配置 2.1 ke ...
- C#的关于窗体的类库方案 - 开源研究系列文章
这次想到了以前编写的关于应用的那个类库,不过当时的只是定义了显示接口,然后调用窗体显示.现在想到要把这个关于窗体的类库进行集合,统一调用,于是就把原来的代码进行了修改完善,终于得到了这次这个例子. 这 ...
- 80x86汇编—80x86架构
文章目录 计算机如何工作 存储器 逻辑地址到物理地址 寄存器 数据寄存器使用细节 其他知识点细节 堆栈Stack 标志寄存器 中断 汇编入门简单,深入难 使用8086架构进行学习,本章节如果没有学过计 ...
- ollama 源代码中值得阅读的部分
阅读 Ollama 源代码以了解其内部工作机制.扩展功能或参与贡献,以下是一些值得重点关注的部分: 1. 核心服务模块: 查找负责启动和管理模型服务的主程序或类,这通常是整个项目的核心逻辑所在.关注如 ...
- AIRIOT答疑第5期|如何使用低代码业务流引擎?
推拉拽! AIRIOT平台业务流引擎可创建丰富的业务流程,实现从流程定义.数据处理.任务工单.消息通知.日志追踪的闭环流转.多类型节点任意组合,可视化流程日志,精准追踪流程流转.人工任务统一管理,审批 ...
- CICD详解之gitlab,Jenkins
持续集成概念 持续集成Continuous Integration 持续交付Continuous Delivery 持续部署Continuous Deployment 什么是持续集成: 持续集成是指开 ...
- 安装anaconda3卡在Unpacking payload ...
ananconda3在centos7虚拟机上,直接进行ananconda3安装但是始终卡在Unpacking payload ..., 虚拟机的核心数调到2或者2以上即可解决
- Python爬图片
1 import requests 2 from lxml import etree 3 4 header = { 5 "user-agent": "Mozilla/5. ...
- Linux运维面试总结
1.Linux系统相关日志 /var/log/message:系统信息日志,包含错误信息 /var/log/secure:系统登录日志 /var/log/maillog:邮件日志 /var/log/c ...