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

【51nod 连续区间】 题解(序列分治)

题目描述

       区间内的元素元素排序后 任意相邻两个元素值差为 1 1 1 的区间称为“连续区间”。
       如 3 , 1 , 2 3,1,2 3,1,2 是连续区间, 3 , 1 , 4 3,1,4 3,1,4 不是连续区间。
       给出一个 1 ∼ n 1 \sim n 1n 的排列,问有多少连续区间。
       n ≤ 1 0 6 n \leq 10^6 n106

分析

       我们考虑对序列分治,设 s o l v e ( l , r ) solve(l,r) solve(l,r) 表示左右端点在区间 [ l , r ] [l, r] [l,r] 内的 “连续区间” 的数量。那么显然, 有:

       s o l v e ( l , r ) = s o l v e ( l , m i d ) + s o l v e ( m i d + 1 , r ) + c a l c ( l , r , m i d ) solve(l, r) = solve(l, mid) + solve(mid + 1, r) + calc(l,r, mid) solve(l,r)=solve(l,mid)+solve(mid+1,r)+calc(l,r,mid)

       其中 c a l c ( l , r , m i d ) calc(l, r, mid) calc(l,r,mid) 表示左端点在 [ l , m i d ] [l, mid] [l,mid], 右端点在 [ m i d + 1 , r ] [mid + 1, r] [mid+1,r] 的 “连续区间” 数量。

       我们接下来考虑如何在 O ( l e n ) O(len) O(len) 的时间复杂度计算 c a l c ( l , r , m i d ) calc(l, r, mid) calc(l,r,mid)

       因为给的序列是 排列,所以有一个性质:对于一个连续区间而言,设它的长度是 k k k,那么有 m a x − m i n + 1 = k max - min + 1= k maxmin+1=k,即最大值减最小值等于区间长度。

       我们考虑区间 [ i , j ] [i, j] [i,j] 是否为合法区间,其中 i ∈ [ l , m i d ] , j ∈ [ m i d + 1 , r ] i \in [l, mid],j \in [mid + 1, r] i[l,mid]j[mid+1,r]

       设
       m a x x i = m a x ( a i , a i + 1 , a i + 2 , . . . , a m i d ) maxx_i = max(a_i, a_{i + 1}, a_{i + 2},..., a_{mid}) maxxi=max(ai,ai+1,ai+2,...,amid)
       m i n x i = m i n ( a i , a i + 1 , a i + 2 , . . . , a m i d ) minx_i = min(a_i, a_{i + 1}, a_{i + 2},..., a_{mid}) minxi=min(ai,ai+1,ai+2,...,amid)
       m a x x j = m a x ( a j , a j − 1 , a j − 2 , . . . , a m i d + 1 ) maxx_j = max(a_j, a_{j - 1}, a_{j - 2}, ..., a_{mid + 1}) maxxj=max(aj,aj1,aj2,...,amid+1)
       m i n x j = m i n ( a j , a j − 1 , a j − 2 , . . . , a m i d + 1 ) minx_j = min(a_j, a_{j - 1}, a_{j - 2}, ..., a_{mid + 1}) minxj=min(aj,aj1,aj2,...,amid+1)

       如果区间 [ l , r ] [l, r] [l,r]合法,那么有 m a x ( m a x x i , m a x x j ) − m i n ( m i n x i , m i n x j ) + 1 = j − i + 1 max(maxx_i, maxx_j) - min(minx_i, minx_j) + 1= j - i + 1 max(maxxi,maxxj)min(minxi,minxj)+1=ji+1
       把左右加 1 1 1 消掉,得到 m a x ( m a x x i , m a x x j ) − m i n ( m i n x i , m i n x j ) = j − i max(maxx_i, maxx_j) - min(minx_i, minx_j) = j - i max(maxxi,maxxj)min(minxi,minxj)=ji

       我们现在只考虑 m a x ( m a x i , m a x j ) max(max_i, max_j) max(maxi,maxj) 等于 m a x i max_i maxi 的情况。另一种情况可以把序列反转后做同样的统计。

       那么现在还可以再分两种情况:

       1 1 1. m i n ( m i n x i , m i n x j ) = m i n x i min(minx_i, minx_j) = minx_i min(minxi,minxj)=minxi:这一种情况我们可以枚举 i i i,然后根据 m a x x i maxx_i maxxi m i n x x i minxx_i minxxi 的大小算出来一个 j j j,然后检验一下是否满足 m i d + 1 ≤ j ≤ r mid + 1\leq j \leq r mid+1jr 以及 是否满足 m a x x j < m a x x i maxx_j < maxx_i maxxj<maxxi 并且 m i n x j > m i n x i minx_j > minx_i minxj>minxi 即可。计算和检验的复杂度都是 O ( 1 ) O(1) O(1) 的。

       2 2 2. m i n ( m i n x i , m i n x j ) = m i n x j min(minx_i, minx_j) = minx_j min(minxi,minxj)=minxj:那么不难发现, 如果 [ i , j ] [i, j] [i,j] 合法,需要满足 :

       m a x x i − m i n x j = j − i ⇒ m a x x i + i = m i n x j + j maxx_i - minx_j = j - i \Rightarrow maxx_i + i = minx_j + j maxximinxj=jimaxxi+i=minxj+j

       因为 m i n x j + j minx_j + j minxj+j 是一个定值, 可以开 记录数量。我们从 m i d mid mid l l l 枚举 i i i, 那么 m a x x i maxx_i maxxi 是不降的, m i n x i minx_i minxi 是不增的。那么由于需要满足 m a x x i > m a x x j maxx_i > maxx_j maxxi>maxxj 并且 m i n x i > m i n x j minx_i > minx_j minxi>minxj,所以我们考虑这两个限制条件相当于是给 j j j 的选择划定了一个范围。

       具体来讲,我们维护一个双指针 l t lt lt r t rt rt。表示在 枚举到 i i i j j j 的范围。 m a x x i maxx_i maxxi 增大那么 r t rt rt 向右移动,在桶里面让 m i n x r t + r t minx_{rt} + rt minxrt+rt 的位置加 1 1 1 m i n x i minx_i minxi 减小那么让 l t lt lt 向右移动,同时在桶里面让 m i n x l t + l t minx_{lt} + lt minxlt+lt 的位置减 1 1 1。指针稳定后统计 桶里面 m a x x i + i maxx_i + i maxxi+i 位置的数量就好了。

       复杂度计算十分典型:
       最多递归 l o g 2 n log_2n log2n 层,每一层的总复杂度是 O ( n ) O(n) O(n)。所以算法复杂度是 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)。可能带点常数。

       代码不难写。

CODE:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
typedef long long LL;
inline int read(){int x = 0, f = 1; char c = getchar();while(!isdigit(c)){if(c == '-') f = -1; c = getchar();}while(isdigit(c)){x = (x << 1) + (x << 3) + (c ^ 48); c = getchar();}return x * f;
}
int n, a[N], b[N], minx[N], maxx[N], barrel[N * 2];
LL res;
LL get(int l, int r, int k){//k是中间点,属于左边  算左边为主导的答案 maxx[k] = minx[k] = b[k]; maxx[k + 1] = minx[k + 1] = b[k + 1];for(int i = k - 1; i >= l; i--){maxx[i] = max(maxx[i + 1], b[i]);minx[i] = min(minx[i + 1], b[i]);}for(int i = k + 2; i <= r; i++){maxx[i] = max(maxx[i - 1], b[i]);minx[i] = min(minx[i - 1], b[i]);}LL ans = 0;for(int i = k; i >= l; i--){// 首先算左边既有最大,又有最小的答案 int rt = maxx[i] - minx[i] + i;if(rt > r || rt <= k) continue;if(maxx[rt] < maxx[i] && minx[rt] > minx[i]) ans++;}int rt = k + 1, lt = k + 1;for(int i = k; i >= l; i--){// 接下来算左边有最大值,右边有最小值的答案 while(maxx[i] > maxx[rt] && rt <= r){barrel[minx[rt] + rt]++;rt++;}while(minx[i] < minx[lt] && lt < rt){barrel[minx[lt] + lt]--;lt++;}ans += barrel[maxx[i] + i];}for(int i = k + 1; i <= r; i++) barrel[minx[i] + i] = 0;return ans;
}
void solve(int l, int r){if(l == r){res++; return ;}int mid = (l + r >> 1);solve(l, mid); solve(mid + 1, r);// 算出来左右两边的答案 for(int i = l; i <= r; i++) b[i] = a[i];res += get(l, r, mid);reverse(b + l, b + r + 1);res += get(l, r, l + r - mid - 1);
}
int main(){n = read();for(int i = 1; i <= n; i++)a[i] = read();solve(1, n);printf("%lld\n", res);return 0;
}

相关文章:

【51nod 连续区间】 题解(序列分治)

题目描述 区间内的元素元素排序后 任意相邻两个元素值差为 1 1 1 的区间称为“连续区间”。 如 3 , 1 , 2 3,1,2 3,1,2 是连续区间&#xff0c; 3 , 1 , 4 3,1,4 3,1,4 不是连续区间。 给出一个 1 ∼ n 1 \sim n 1∼n 的排列&#xff0c;问有多少连续区间。 …...

10.30校招 实习 内推 面经

绿*泡*泡&#xff1a; neituijunsir 交流裙 &#xff0c;内推/实习/校招汇总表格 1、校招&#xff5c;极目智能2024届校招 校招&#xff5c;极目智能2024届校招 2、校招&#xff5c;杭州极弱磁场国家重大科技基础设施研究院2024秋季校园招聘正式启动&#xff01; 校招&…...

相比typescript,python的动态类型有什么优缺点?

以下是Python的动态类型相对于TypeScript的静态类型的一些优缺点&#xff1a; 1、Python的动态类型优点&#xff1a; 更灵活&#xff1a;Python的动态类型允许你在运行时更灵活地改变变量的类型&#xff0c;这对于快速原型设计和快速开发非常有帮助。 代码更简洁&#xff1a;…...

高效处理文件:批量顺序编号重命名方法

每个人都面临着文件管理的挑战&#xff0c;特别是那些需要处理大量文件的人。如何高效地管理这些文件一直是一个难题。为了解决这个问题&#xff0c;我向大家推荐一款强大的文件管理工具——固乔文件管家。这个工具可以帮助你快速有效地给文件进行批量重命名和编号&#xff0c;…...

JAVA深化篇_29—— 线程使用之线程联合以及Thread类中的其他常用方法【附有详细说明及代码案例】

线程联合 当前线程邀请调用方法的线程优先执行&#xff0c;在调用方法的线程执行结束之前&#xff0c;当前线程不能再次执行。线程A在运行期间&#xff0c;可以调用线程B的join()方法&#xff0c;让线程B和线程A联合。这样&#xff0c;线程A就必须等待线程B执行完毕后&#xf…...

〖Python网络爬虫实战㊲〗- JavaScript 逆向实战(一)

订阅:新手可以订阅我的其他专栏。免费阶段订阅量1000+python项目实战 Python编程基础教程系列(零基础小白搬砖逆袭) 说明:本专栏持续更新中,订阅本专栏前必读关于专栏〖Python网络爬虫实战〗转为付费专栏的订阅说明作者:爱吃饼干的小白鼠。Python领域优质创作者,2022年度…...

2023辽宁省数学建模A题铁路车站的安全标线完整原创论文详细讲解(含matlab代码)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了辽宁省数学建模A题完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 B预计下午两点前更新完毕&#xff0c;A全…...

(14)学习笔记:动手深度学习(Pytorch神经网络基础)

文章目录 神经网络的层与块块的基本概念自定义块 问答 神经网络的层与块 块的基本概念 以多层感知机为例&#xff0c; 整个模型接受原始输入&#xff08;特征&#xff09;&#xff0c;生成输出&#xff08;预测&#xff09;&#xff0c; 并包含一些参数&#xff08;所有组成层…...

Leetcode-1 两数之和

暴力穷举 class Solution {public int[] twoSum(int[] nums, int target) {int[] num new int[2];for(int i0;i<nums.length-1;i){for(int ji1;j<nums.length;j){if(nums[i]nums[j]target){num[0]i;num[1]j;}}}return num;} }HashMap&#xff0c;记录下标和对应值&…...

Screens for Mac 中文版 远程桌面连接控制工具

Screens Mac 版是Mac os平台上的一款Mac VNC 客户终端,能够自由访问远程计算机设备&#xff0c; Screens Mac 版支持各种强大的远程控制辅助工具&#xff0c;例如剪切板共享、快捷方式自定义、安全连接、多屏幕支持、快速扫描连接等。 Screens 4 for mac支持多种远程桌面协议&…...

解决vmware安装ubuntu虚拟机显示不全以及无法实现windows与虚拟机之间无法相互复制粘贴问题

01、存在问题 02、解决方案 sudo apt-get autoremove open-vm-tools sudo apt-get install open-vm-tools sudo apt-get install open-vm-tools-desktop reboot //重启重启后界面如下&#xff1a; 存在Bug 如果遇到一下问题&#xff0c;请先执行下列命令&#x…...

希腊字母读音表

序号大写小写英文注音国际音标注音中文读音意义1Ααalphaa:lf阿尔法角度&#xff1b;系数2Ββbetabet贝塔磁通系数&#xff1b;角度&#xff1b;系数3Γγgammaˈɡmə伽马电导系数&#xff08;小写&#xff09;4Δδdeltadelt德尔塔变动&#xff1b;密度&#xff1b;屈光度5…...

如何使用CodeceptJS、Playwright和GitHub Actions构建端到端测试流水线

介绍 端到端测试是软件开发的一个重要方面&#xff0c;因为它确保系统的所有组件都能正确运行。CodeceptJS是一个高效且强大的端到端自动化框架&#xff0c;与Playwright 结合使用时&#xff0c;它成为自动化Web、移动甚至桌面 (Electron.js) 应用程序比较好用的工具。 在本文中…...

解析python爬取Ebay数据的方式

前言 Ebay是全球著名的电子商务平台之一&#xff0c;每天都有海量的商品信息涌入其中&#xff0c;在电商行业获取这些数据试试非常有价值的&#xff0c;为了更好地了解市场动态&#xff0c;掌握更多的电商行情。Python爬虫成为了必不可少的工具&#xff0c;本文将通过使用Http…...

设置DevC++支持c++11标准

1.点击编译选项 2. 设置语言标准 3.点击确认 4.测试代码 使用auto成功 测试&#xff01;...

腾讯云服务器CVM详细介绍_优缺点亲自整理

腾讯云服务器CVM提供安全可靠的弹性计算服务&#xff0c;腾讯云明星级云服务器&#xff0c;弹性计算实时扩展或缩减计算资源&#xff0c;支持包年包月、按量计费和竞价实例计费模式&#xff0c;CVM提供多种CPU、内存、硬盘和带宽可以灵活调整的实例规格&#xff0c;提供9个9的数…...

06_es分布式搜索引擎2

一、DSL查询文档 1.DSL查询分类 ①查询所有&#xff1a;match_all ②全文检索&#xff1a;利用分词器对用户输入的内容分词&#xff0c;倒排索引去匹配 match_query multi_match_query ③精确查询&#xff1a;根据精确词条查找数据&#xff0c;查找的是keyword,数值,日期,b…...

【3D图像分割】基于 Pytorch 的 VNet 3D 图像分割3(3D UNet 模型篇)

在本文中&#xff0c;主要是对3D UNet 进行一个学习和梳理。对于3D UNet 网上的资料和GitHub直接获取的代码很多&#xff0c;不需要自己从0开始。那么本文的目的是啥呢&#xff1f; 本文就是想拆解下其中的结构&#xff0c;看看对于一个3D的UNet&#xff0c;和2D的UNet&#x…...

【源码解析】Spring Bean定义常见错误

案例1 隐式扫描不到Bean的定义 RestController public class HelloWorldController {RequestMapping(path "/hiii",method RequestMethod.GET)public String hi() {return "hi hellowrd";}}SpringBootApplication RestController public class Applicati…...

由于找不到vcruntime140.dll无法继续执行代码

在计算机使用过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“vcruntime140.dll丢失”。这个错误通常发生在运行某些程序或游戏时&#xff0c;它会导致程序无法正常运行。那么&#xff0c;如何解决vcruntime140.dll丢失的问题呢&#xff1f;本文将介绍…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...

向量几何的二元性:叉乘模长与内积投影的深层联系

在数学与物理的空间世界中&#xff0c;向量运算构成了理解几何结构的基石。叉乘&#xff08;外积&#xff09;与点积&#xff08;内积&#xff09;作为向量代数的两大支柱&#xff0c;表面上呈现出截然不同的几何意义与代数形式&#xff0c;却在深层次上揭示了向量间相互作用的…...