【Codeforces】CF 2009 G2

news2024/10/8 15:28:44

Yunli’s Subarray Queries (hard version)

#莫队 #数据结构 #线段树 #单调栈

题目描述

This is the hard version of the problem. In this version, it is guaranteed that r ≥ l + k − 1 r \geq l+k-1 rl+k1 for all queries.

For an arbitrary array b b b, Yunli can perform the following operation any number of times:

  • Select an index i i i. Set b i = x b_i = x bi=x where x x x is any integer she desires ( x x x is not limited to the interval [ 1 , n ] [1,n] [1,n]).

Denote f ( b ) f(b) f(b) as the minimum number of operations she needs to perform until there exists a consecutive subarray ∗ ^{\text{∗}} of length at least k k k in b b b.

Yunli is given an array a a a of size n n n and asks you q q q queries. In each query, you must output ∑ j = l + k − 1 r f ( [ a l , a l + 1 , … , a j ] ) \sum_{j=l+k-1}^{r} f([a_l, a_{l+1}, \ldots, a_j]) j=l+k1rf([al,al+1,,aj]).

∗ ^{\text{∗}} If there exists a consecutive subarray of length k k k that starts at index i i i ( 1 ≤ i ≤ ∣ b ∣ − k + 1 1 \leq i \leq |b|-k+1 1ibk+1), then b j = b j − 1 + 1 b_j = b_{j-1} + 1 bj=bj1+1 for all i ≤ j ≤ i + k − 1 i \leq j \leq i+k-1 iji+k1.

输入格式

The first line contains t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1t104) — the number of test cases. The first line of each test case contains three integers n n n, k k k, and q q q ( 1 ≤ k ≤ n ≤ 2 ⋅ 1 0 5 1 \leq k \leq n \leq 2 \cdot 10^5 1kn2105, 1 ≤ q ≤ 2 ⋅ 1 0 5 1 \leq q \leq 2 \cdot 10^5 1q2105) — the length of the array, the length of the consecutive subarray, and the number of queries. The following line contains n n n integers a 1 , a 2 , . . . , a n a_1, a_2, ..., a_n a1,a2,...,an ( 1 ≤ a i ≤ n 1 \leq a_i \leq n 1ain). The following q q q lines contain two integers l l l and r r r ( 1 ≤ l ≤ r ≤ n 1 \leq l \leq r \leq n 1lrn, r ≥ l + k − 1 r \geq l+k-1 rl+k1) — the bounds of the query. It is guaranteed the sum of n n n over all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2105 and the sum of q q q over all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2105.

输出格式

Output ∑ j = l + k − 1 r f ( [ a l , a l + 1 , … , a j ] ) \sum_{j=l+k-1}^{r} f([a_l, a_{l+1}, \ldots, a_j]) j=l+k1rf([al,al+1,,aj]) for each query on a new line.

样例 #1

样例输入 #1

3
7 5 3
1 2 3 2 1 2 3
1 7
2 7
3 7
8 4 2
4 3 1 1 2 4 3 2
3 6
1 5
5 4 2
4 5 1 2 3
1 4
1 5


样例输出 #1

6
5
2
2
5
2
3

解法

解题思路

延续之前 e a s y easy easy版本的做法,我们可以预处理出所有 k k k大小窗口的 f ( 1 ) , f ( 2 ) . . . f ( n − k + 1 ) f(1),f(2)...f(n-k + 1) f(1),f(2)...f(nk+1),这里使用莫队来预处理。

容易发现, f ( 2 ) f(2) f(2)可以取 m i n ( f ( 2 ) , f ( 3 ) ) min(f(2),f(3)) min(f(2),f(3)) f ( 1 ) f(1) f(1)可以取 m i n ( f ( 1 ) , f ( 2 ) , f ( 2 ) ) min(f(1),f(2),f(2)) min(f(1),f(2),f(2))…,因此我们处理后的 f f f实际上是低调不增的。

h a r d hard hard版本中,我们需要求的 f ( l ) , f ( l + 1 ) , f ( l + 2 ) . . . f ( r − k + 1 ) f(l),f(l+1),f(l+2)...f(r-k+1) f(l),f(l+1),f(l+2)...f(rk+1)这些的和,这一部分显然是可以通过线段树来求和的。

同样我们采用离线的方式,把询问存起来,这里按照左端点从大到小来排序。

考虑枚举左端点 i i i,然后通过 f ( i ) f(i) f(i)来更新, f ( i + 1 ) f(i+1) f(i+1)包含的区间,因为更新的区间一定是一段单调不增的区间。这部分可以使用单调栈来找到第一个小于等于 f ( i ) f(i) f(i)的值,或者直接二分那个位置即可。

而更新操作就使用线段树推平赋值即可,最后判断每个查询 [ l , r ] [l,r] [l,r]是否在区间内,通过线段树区间求和来更新答案。

代码

 
 
const int N = 2e5 + 10;
int n, m, k, len;
struct Mos {
	int l, r, id;
	bool operator<(Mos& x) {
		if ((l - 1) / len + 1 != (x.l - 1) / len + 1) return l < x.l;
		if (((l - 1) / len + 1) & 1) return r < x.r;
		else return r > x.r;
	}
};
 
struct node {
	int l, r;
	ll sum, flg;
}tr[N * 4];
 
void pushup(int u) {
	tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
 
void build(int u, int l, int r) {
	if (l == r) tr[u] = { l, r, 0, -1 };
	else {
		tr[u] = { l, r, 0, -1 };
		int mid = l + r >> 1;
		build(u << 1, l, mid);
		build(u << 1 | 1, mid + 1, r);
		pushup(u);
	}
}
 
void pushdown(int u) {
	node& root = tr[u], & ls = tr[u << 1], & rs = tr[u << 1 | 1];
	if (root.flg != -1) {
		ls.sum = (ls.r - ls.l + 1ll) * root.flg;
		ls.flg = root.flg;
		rs.sum = (rs.r - rs.l + 1ll) * root.flg;
		rs.flg = root.flg;
		root.flg = -1;
	}
}
 
void modify(int u, int l, int r, int c) {
	if (tr[u].l >= l && tr[u].r <= r) {
		tr[u].sum = (tr[u].r - tr[u].l + 1ll) * c;
		tr[u].flg = c;
	}
	else {
		pushdown(u);
		int mid = tr[u].l + tr[u].r >> 1;
		if (l <= mid) modify(u << 1, l, r, c);
		if (r > mid) modify(u << 1 | 1, l, r, c);
		pushup(u);
	}
}
 
ll query(int u, int l, int r) {
	if (tr[u].l >= l && tr[u].r <= r) return tr[u].sum;
	else {
		pushdown(u);
		int mid = tr[u].l + tr[u].r >> 1;
		ll res = 0;
		if (l <= mid) res += query(u << 1, l, r);
		if (r > mid) res += query(u << 1 | 1, l, r);
		return res;
	}
}
 
int stk[N];
int a[N],f[N];
void solve() {
	std::cin >> n >> k >> m;
 
	len = 350;
	for (int i = 1; i <= n; ++i) {
		std::cin >> a[i];
	}
 
	std::vector<Mos>q(n + 1);
	for (int i = 1; i <=n-k+1 ; ++i) {
		int l = i, r = l + k - 1;
		q[i] = { l,r,i };
	}
 
	std::vector<int>mp(2 * n + 1);
	std::multiset<int>mst;
	sort(q.begin() + 1, q.begin() + n - k + 2);
 
	auto add = [&](int idx) {
		mst.extract(mp[a[idx] - idx + n]);
		mp[a[idx] - idx + n]++;
		mst.insert(mp[a[idx] - idx + n]);
		};
 
	auto del = [&](int idx) {
		mst.extract(mp[a[idx] - idx + n]);
		mp[a[idx] - idx + n]--;
		mst.insert(mp[a[idx] - idx + n]);
		};
 
	int l = 1, r = 0;
 
	for (int i = 1; i <= n-k+1; ++i) {
		while (l > q[i].l) 	add(--l);
		while (l < q[i].l) del(l++);
		while (r < q[i].r) add(++r);
		while (r > q[i].r) del(r--);
		int len = r - l + 1;
 
		f[q[i].id] = len - *mst.rbegin();
 
	}
 
	std::vector<std::array<int, 3>>Q;
	for (int i = 1; i <= m; ++i) {
		int l, r;
		std::cin >> l >> r;
		Q.push_back({ l,r, i });
	}
 
	sort(Q.begin(), Q.end(),
		[&](const std::array<int, 3>& x, const std::array<int, 3>& y) {
			return x[0] > y[0];
		});
 
	int p = 0;
	int tt = 0;
	int ed = n - k + 1;
 
 
	build(1, 1, ed);
	std::vector<int>ans(m + 1);
 
	for (int i = ed; i >= 1; i--) {
		while (tt && f[stk[tt - 1]] >= f[i]) tt--;
 
		if (tt) modify(1, i, stk[tt - 1] - 1, f[i]);
		
		else modify(1, i, ed, f[i]);
		
		while (p < Q.size() && Q[p][0] == i) {
			ans[Q[p][2]] = query(1, Q[p][0], Q[p][1] - k + 1);
			p++;
		}
		stk[tt++] = i;
	}
 
	for (int i = 1; i <= m; i++) {
		std::cout << ans[i] << "\n";
	}
 
}
 
signed main() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
 
	int t = 1;
	std::cin >> t;
 
	while (t--) {
		solve();
	}
}

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

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

相关文章

纯干货!一个白帽子挖漏洞经验细致分享_白帽子找漏洞一天能多少

不知道是不是很多人和我一样&#xff0c;每天刷着漏洞&#xff0c;看着自己的排名一位一位的往上提升&#xff0c;但是&#xff0c;但是。总感觉怪怪的&#xff0c;为什么别人刷的漏洞都是现金&#xff0c;而自己刷的漏洞都是给库币。别人一天为什么提交那么多漏洞&#xff0c;…

winform appconfig

文章目录 添加一个appconfig配置文件的结构读取写入 这是wiform自带的配置文件&#xff0c;格式为xml 其位置在程序根目录下 添加一个appconfig 首先默认情况下&#xff0c;winform会自动创建一个名叫appconfig的配置文件&#xff0c;位于程序根目录下 如果需要手动创建更多…

【路径规划】基于球面向量的粒子群优化算法(SPSO)

摘要 本文提出了一种基于球面向量的粒子群优化算法&#xff08;Spherical Vector-based Particle Swarm Optimization, SPSO&#xff09;用于解决路径规划问题。该算法通过球面坐标系表示粒子的位置更新&#xff0c;增强了搜索空间的探索能力和全局优化性能。通过与遗传算法&a…

浅析基于双碳目标的光储充一体化电站状态评估技术

摘要&#xff1a;全国碳市场拉开了我国能源结构加速转型的大幕&#xff0c;催生了光伏、储能和新能源汽车等一批绿色产业的兴起&#xff0c;同时随着利好政策扶植和消费者的青睐&#xff0c;光伏、储能和新能源汽车市场均加快发展。但传统的充电桩和光伏电站都是分开建设&#…

基于SSM的家庭理财系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 选题目的: 随着社会的进步&#xff0c;我国经济的快速发展&#xff0c;人们的生活水平提高了&#xff0c;现在人们已经不仅仅满足于能够吃得饱穿得好&#xff0c;现在的人们在想着如何丰富自己的精神世界&#xff0c;想着如何去…

Win11环境下 DELPHI 12.2 安装全过程

背景描述 DELPHI作为曾经的Windows原生开发的王者&#xff0c;DELPHI12.2可以实现Windows、Android、IOS、macOS、Linux的应用开发&#xff0c;现在还有少数企业使用&#xff0c;大多数用户是从传统D3/4/5/6/7坚持下来的爱好者&#xff0c;2ccc.com里有相关内容&#xff0c;但…

基于方块编码的图像压缩matlab仿真,带GUI界面

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 编码单元的表示 4.2编码单元的编码 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 下图是随着方块大小的变化&#xff0c;图像的压缩率以及对应的图像质量指标PSN…

QT使用websocket实现语音对讲

简介&#xff1a; 本文所描述的功能和代码&#xff0c;是基于QT的开发环境。在QT上使用websocket&#xff0c;接受和发送pcm音频&#xff0c;实现了语音对讲功能。经自测&#xff0c;该功能可以正常使用&#xff0c;以下是相关代码的分享。 void MainWindow::on_pushButton_Ope…

Linux学习笔记(七):磁盘的挂载与扩展

Linux学习笔记&#xff08;七&#xff09;&#xff1a;磁盘的挂载与扩展 在虚拟机环境中&#xff0c;当我们的存储空间不足时&#xff0c;添加一块新的硬盘显得尤为重要。 1. 新增磁盘 首先&#xff0c;你需要确保有一块物理磁盘或虚拟磁盘。在虚拟机管理器中&#xff0c;你可以…

1.4TB! 全台湾2024年三维建筑模型3DTiles数据

在今年1月13日&#xff0c;我写了一篇文章&#xff0c;详细介绍了了全台湾2023年三维建筑模型数据以及数据背景。隔了8个月之后&#xff0c;我对全岛建筑模型数据进行了更新,不仅在数量上有增长&#xff0c;而且数据显示性能也进行了优化&#xff0c;下面我针对对2024年数据进行…

探索Python文本处理的新境界:textwrap库揭秘

文章目录 **探索Python文本处理的新境界&#xff1a;textwrap库揭秘**一、背景介绍二、textwrap库是什么&#xff1f;三、如何安装textwrap库&#xff1f;四、简单函数使用方法4.1 wrap()4.2 fill()4.3 shorten()4.4 dedent()4.5 indent() 五、实际应用场景5.1 格式化日志输出5…

黑龙江等保测评详细指南

一、什么是等保测评&#xff1f; 等保&#xff08;信息安全等级保护&#xff09;是指根据信息系统的重要性和安全需求&#xff0c;对其进行分级保护的制度。黑龙江省的等保测评旨在评估信息系统的安全性&#xff0c;确保其符合国家和地方的安全标准。 二、等保测评的必要性 1…

OpenAI重磅发布Canvas:跟ChatGPT一起写作编程

现在是大半夜1点56&#xff0c;国庆第三天&#xff0c;我想睡觉&#xff0c;真的。 但是&#xff0c;ChatGPT更新了&#xff0c;虽然不是那种王炸级的新模型模型更新&#xff0c;但是更新了一个极度优雅&#xff0c;对普通人极度友好的功能。 而且&#xff0c;顺带&#xff0…

ASB:LLM智能体应用攻防测试数据集

ABS&#xff1a;LLM智能体应用攻防测试数据集 Agent应用 Agent Security Bench (ASB): Formalizing and Benchmarking Attacks and Defenses in LLM-based Agents 尽管基于 LLM 的代理能够通过外部工具和记忆机制解决复杂任务&#xff0c;但也可能带来严重安全风险。现有文献对…

地图可视化的艺术:深入比较Mapbox、OpenLayers、Leaflet和Cesium,不同场景下应如何选择地图库

目录 地图可视化的艺术&#xff1a;深入比较Mapbox、OpenLayers、Leaflet和Cesium 一、总览 二、定制地图美学的先行者——Mapbox 1、主要功能特点 2、开源情况 3、市场与应用人群 4、安装与基础使用代码 三、开源GIS地图库的全能王——OpenLayers 1、主要功能特点 2…

重要的事情说两遍!Prompt「复读机」,显著提高LLM推理能力

【导读】 尽管大模型能力非凡&#xff0c;但干细活的时候还是比不上人类。为了提高LLM的理解和推理能力&#xff0c;Prompt「复读机」诞生了。 众所周知&#xff0c;人类的本质是复读机。 我们遵循复读机的自我修养&#xff1a;敲黑板&#xff0c;划重点&#xff0c;重要的事…

原生input实现时间选择器用法

2024.10.08今天我学习了如何用原生的input&#xff0c;实现时间选择器用法&#xff0c;效果如下&#xff1a; 代码如下&#xff1a; <div><input id"yf_start" type"text"> </div><script>$(#yf_start).datepicker({language: zh…

ELK中L的filebeat配置及使用(超详细)

上一次讲解了如何在linux服务器上使用docker配置ELK中的E和K&#xff0c;这期着重讲解一下L怎么配置。 首先L在elk中指的是一个数据处理管道&#xff0c;可以从多种来源收集数据&#xff0c;进行处理和转换&#xff0c;然后将数据发送到 Elasticsearch。L的全称就是&#xff1…

国外电商系统开发-运维系统文件下载

文件下载&#xff0c;作者设计的比较先进&#xff0c;如果下载顺利&#xff0c;真的还需要点两次鼠标&#xff0c;所有的远程文件就自动的下载到了您的PC电脑上了。 现在&#xff0c;请您首选选择要在哪些服务器上下载文件&#xff1a; 选择好了服务器以后&#xff0c;现在选择…

【智能算法应用】人工水母搜索算法求解二维路径规划问题

摘要 本文应用人工水母搜索算法&#xff08;Jellyfish Search, JFS&#xff09;求解二维空间中的路径规划问题。水母搜索算法是一种新型的智能优化算法&#xff0c;灵感来源于水母的群体运动行为&#xff0c;通过模仿水母的觅食、漂浮等行为&#xff0c;实现全局最优路径的搜索…