数据结构 Trick 之:区间子区间计数

news/2025/9/18 15:59:56/文章来源:https://www.cnblogs.com/porse114514/p/19098973

能够解决的问题

  • \(O(n \log n)\) 可过。
  • 维护数列,无修改每次查询一个区间的所有子区间
  • 离线

思路

看到一个区间的所有子区间这种查询,直接做显然是做不了的。

考虑离线,那么将询问区间进行右端点排序,然后就可以扫描线搞掉一维。

我们从左往右枚举 \(r\) 维护线段树 \(t\) 使得 \(t_l\) 维护的是区间 \([l, r]\)。在每次将 \(r\) 向右移的时候做一次修改。

但是此时还有一个问题,这样单词只能处理一个 \(r\),多个 \(l\),那么就要请出我们的历史信息线段树,这样就 OK 了。

例题与代码

CF997E Good Subsegments - 洛谷

标准的模板。

容易发现好区间就是 \((max - min) - (r - l) = 0\) 的区间,于是直接维护即可。至于极值的修改,用一个单调栈即可。

#include <bits/stdc++.h>
using namespace std;namespace gxk {void main() ;
}
int main() {ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);gxk::main();return 0;
}// ---#define int long long
#define umidd ((nodes[u].l + nodes[u].r) >> 1)
#define usz (nodes[u].r - nodes[u].l + 1)
namespace gxk {constexpr int maxn = 120010;int n, m, a[maxn], ans[maxn];struct qu {int l, r;} q[maxn];struct segnode {int l, r, minn, sum, hsum, tag, htag;} ;struct segtree {segnode nodes[maxn << 2];void pushup(int u) {nodes[u].minn = min(nodes[u << 1].minn, nodes[u << 1 | 1].minn);nodes[u].sum = 0;if (nodes[u << 1].minn == nodes[u].minn) nodes[u].sum += nodes[u << 1].sum;if (nodes[u << 1 | 1].minn == nodes[u].minn) nodes[u].sum += nodes[u << 1 | 1].sum;nodes[u].hsum = nodes[u << 1].hsum + nodes[u << 1 | 1].hsum;return ;}void build(int u, int l, int r) {nodes[u].l = l, nodes[u].r = r;if (usz == 1) {nodes[u].minn = l;nodes[u].sum = 1;return ;}build(u << 1, l, umidd);build(u << 1 | 1, umidd + 1, r);pushup(u);return ;}void modify(int u, int k) {nodes[u].minn += k;nodes[u].tag += k;return ;}void hmodify(int u, int k) {nodes[u].hsum += nodes[u].sum * k;nodes[u].htag += k;return ;}void pushdown(int u) {if (nodes[u].tag) {modify(u << 1, nodes[u].tag);modify(u << 1 | 1, nodes[u].tag);nodes[u].tag = 0;}if (nodes[u].htag) {if (nodes[u << 1].minn == nodes[u].minn) hmodify(u << 1, nodes[u].htag);if (nodes[u << 1 | 1].minn == nodes[u].minn) hmodify(u << 1 | 1, nodes[u].htag);nodes[u].htag = 0;}return ;}void update(int u, int l, int r, int k) {if (nodes[u].l > r || nodes[u].r < l) return ;if (nodes[u].l >= l && nodes[u].r <= r) {modify(u, k);return ;}pushdown(u);update(u << 1, l, r, k);update(u << 1 | 1, l, r, k);pushup(u);return ;}int query(int u, int l, int r) {if (nodes[u].l > r || nodes[u].r < l) return 0;if (nodes[u].l >= l && nodes[u].r <= r) return nodes[u].hsum;pushdown(u);return query(u << 1, l, r) + query(u << 1 | 1, l, r);}} t;struct edge {int l, idx;} ;vector <edge> G[maxn];stack <edge> sx, sn;void main() {cin >> n;for (int i = 1; i <= n; i++) {cin >> a[i];}t.build(1, 1, n);cin >> m;for (int i = 1; i <= m; i++) {cin >> q[i].l >> q[i].r;G[q[i].r].push_back({q[i].l, i});}sx.push({1145141919, 0});sn.push({-1145141919, 0});for (int i = 1, l, r, d; i <= n; i++) {t.modify(1, -1);while (sx.top().l < a[i]) {r = sx.top().idx;d = sx.top().l;sx.pop();l = sx.top().idx + 1;
//				cout << l << ' ' << r << '\n';t.update(1, l, r, a[i] - d);}sx.push({a[i], i});while (sn.top().l > a[i]) {r = sn.top().idx;d = sn.top().l;sn.pop();l = sn.top().idx + 1;
//				cout << l << ' ' << r << '\n';t.update(1, l, r, d - a[i]);}sn.push({a[i], i});t.hmodify(1, 1);for (edge now : G[i]) {ans[now.idx] = t.query(1, now.l, i);}}for (int i = 1; i <= m; i++) {cout << ans[i] << '\n';}return ;}
}

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

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

相关文章

mapstruct.Mapper|Mapping详解

------------------------------------------------------------------------------------------ org.mapstruct.Mapper 和 org.mapstruct.Mapping 是 MapStruct 框架中的核心注解,用于实现 Java 对象之间的自动映射。…

抽象代数-学习笔记

主要积累一些遇到的例子、题目。不定时更新。 运算有结合律的运算:普通/复数/矩阵/模意义下加法、乘法,映射复合,与或异或/集合相关, min/max。 仅仅满足部分群公理:\(\mathbb{N}^*, \mathbb{N}\)。\(\{0,1,2\}\)…

如何在保证质量的前提下,快速完成一份 PPT?

这是一个非常经典且普遍的问题,尤其对于产品经理、咨询顾问等角色来说,PPT既是生产力工具,也是时间吞噬黑洞。你能意识到这个问题并寻求解决方案,已经领先了很多人。 在保证质量的前提下快速完成PPT,绝非单纯追求…

XXL-JOB(3)

XXL-JOB(3)开发Bean模式(基于方法)Bean模式任务,支持基于方法的开发方式,每个任务对应一个方法。基于方法开发的任务,底层会生成JobHandler代理,和基于类的方式一样,任务也会以JobHandler的形式存在于执行器任务…

ClickHouse 表引擎深度解析:ReplacingMergeTree、PARTITION、PRIMARY KEY、ORDER BY 详解 - 若

ClickHouse 表引擎深度解析:ReplacingMergeTree、PARTITION、PRIMARY KEY、ORDER BY 详解 前言 ClickHouse 作为高性能的列式数据库,其表引擎设计是其核心优势之一。ReplacingMergeTree 是处理重复数据的利器,而 PA…

UOS统信服务器操作系统V20(1070)安装mysql8.4.5(建议安装glibc2.28版本)

环境:OS:UOS Server 20 统信服务器操作系统V20(1070)mysql:8.4.5 glib.2.17 操作系统下载https://www.chinauos.com/resource/download-server查看系统glibc版本[root@localhost yum.repos.d]# ldd --versionldd (GNU …

web5(phps源码泄露)

访问index.phps,会自动下载index.php文件 点击查看即可得到flag

web3(自带网络工具包查看数据)

查看源码什么也没有扫目录也什么都没有只能说信息收集能力还欠佳, 我们可以先尝试使用浏览器自带的网络工具查看一下数据包。

web17(备份的sql文件泄露)

用常见的数据库工具打开即可

web11(通过Dns检查查询Flag)

:::info 223.5.5.5测试的解析结果是否具有代表性?(来自阿里云官网)具备一定的代表性,在国内客户端使用223.5.5.5有一定的用户群体,但是该测试结果并不能代表全部用户;如果223.5.5.5测试已经生效,但是您本地仍然不…

ctfshow_web11

ctf.show_web11简单的代码审计,这段代码定义了一个名为replaceSpecialChar的函数,该函数接受一个字符串$strParam作为参数。函数内部使用了正则表达式$regex来匹配SQL语句中的一些关键字,包括select、from、where、…

ctfshow_web13

ctf.show_web13今天也算是碰到一个新类型的文件上传类的题目(与文件包含结合了可以说)首先尝试了直接传一句话木马,全都被ban了,算是没招了就扫了下目录,进去看一眼,好像页面没回显什么东西,再试试看upload.php…

ctfshow_web9

ctf.show_web9尝试爆破无果,应该不是弱口令爆破题,那么我们就扫一下目录进去看看访问该目录后会自动下载一个php文件,打开看看可以看出这是一个sql注入漏洞,通过post传参一个paasword的变量值。经过md5加密后被用来…

强烈推荐 | 阿里开源的这11个神级项目

前言 最近趁着国庆节放假休息,特地整理了一下,阿里巴巴开源的10款神级项目。 这些开源项目中的绝大多数,我都在实际工作中用过,或者有同事用过。确实挺不错,挺有价值的,现在推荐给大家。 1. Druid Druid自称是Ja…

pom 依赖

</build> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifa…

立创商城

立创商城https://www.szlcsc.com/

应急响应-日志分析 - voasem

web服务器日志在很多时候,我们经常需要分析网站的日志,以此来查看网站运行的各种情况。比如说如果网站被攻击,我们可以通过查看日志来溯源攻击者。 Apache 日志目录:/Apache/logs/logs目录下有两个文件,一个是 ac…

ctfshow web 10

ctfshow web 10打开题目长这样,点击取消会自动下载indexs.php文件,打开查看源码 <?php$flag="";function replaceSpecialChar($strParam){$regex = "/(select|from|where|join|sleep|and|\s|unio…

【ACM出版】第四届公共管理、数字经济与互联网技术国际学术会议(ICPDI 2025)

第四届公共管理、数字经济与互联网技术国际学术会议(ICPDI 2025)定于2025年9月26-28日在中国-北京举行。【高录用快见刊、检索:审稿录用速度快】 【录用信息完整:含ISSN号,DOI,封面目录】 第四届公共管理、数字经…