NOIP2023模拟8联测29 集合

news/2024/9/6 6:10:48 标签: 题解, c++

题目大意

定义一个整数集合 S S S是好的,当且仅当 S S S中所有值域连续段的长度都不超过 k k k

换句话说, S S S是好的,当且仅当不存在一对整数 l , r l,r l,r,满足 [ l , r ] [l,r] [l,r]中的整数都在 S S S中出现且 r − l + 1 > k r-l+1>k rl+1>k

给定一个长度为 n n n的序列 a 1 , a 2 , ⋯   , a n a_1,a_2,\cdots,a_n a1,a2,,an,问该序列有多少个子区间满足这个区间的数的集合是好的。

1 ≤ n ≤ 2 × 1 0 5 , 1 ≤ a i , k ≤ n 1\leq n\leq 2\times 10^5,1\leq a_i,k\leq n 1n2×105,1ai,kn


题解

首先,我们可以发现,如果区间 [ l , r ] [l,r] [l,r]是好的,那所有被区间 [ l , r ] [l,r] [l,r],包含的区间也是好的因为这样最长值域连续段长度不会变大,一定也满足条件。

我们可以用扫描线,从小到大枚举右端点,然后维护最小的 l l l,满足区间 [ l , r ] [l,r] [l,r]是好的。

那哦们怎么判断一个区间是不是好的呢?我们用线段树来维护 a i a_i ai的值域,线段树上的每个节点维护区间中最长值域连续段的长度,以及包含左、右端点的极长连续段长度。判断当前区间是否是好的,只需要看根节点维护区间中最长值域连续段的长度是否超过 k k k即可。如果超过了,则将 a l a_l al在线段树上删去。 r r r每往右一个位置,就将 a r a_r ar在线段树上加上。也就是说,线段树只需要支持单点修改。

对于每个 r r r和其对应的最小的 l l l a n s + = r − l + 1 ans+=r-l+1 ans+=rl+1

时间复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn)

code

#include<bits/stdc++.h>
#define lc k<<1
#define rc k<<1|1
using namespace std;
const int N=200000;
int n,k,a[N+5],ct[4*N+5],mx[4*N+5],lx[4*N+5],rx[4*N+5];
long long ans=0;
void ch(int k,int l,int r,int x,int v){
	if(l==r&&l==x){
		ct[k]+=v;
		mx[k]=lx[k]=rx[k]=(ct[k]>0);
		return;
	}
	int mid=l+r>>1;
	if(x<=mid) ch(lc,l,mid,x,v);
	else ch(rc,mid+1,r,x,v);
	if(lx[lc]<mid-l+1) lx[k]=lx[lc];
	else lx[k]=lx[lc]+lx[rc];
	if(rx[rc]<r-mid) rx[k]=rx[rc];
	else rx[k]=rx[rc]+rx[lc];
	mx[k]=max(rx[lc]+lx[rc],max(mx[lc],mx[rc]));
}
int main()
{
//	freopen("set.in","r",stdin);
//	freopen("set.out","w",stdout);
//	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1,j=1;i<=n;i++){
		ch(1,1,n,a[i],1);
		while(mx[1]>k){
			ch(1,1,n,a[j],-1);++j;
		}
		ans+=i-j+1;
	}
	printf("%lld",ans);
	return 0;
}

http://www.niftyadmin.cn/n/5140755.html

相关文章

MATLAB野外观测站生态气象数据处理分析实践应用

1.基于MATLAB语言 2.以实践案例为主&#xff0c;提供所有代码 3.原理与操作结合 4.布置作业&#xff0c;答疑与拓展 示意图&#xff1a; 以野外观测站高频时序生态气象数据为例&#xff0c;基于MATLAB开展上机操作&#xff1a; 1.不同生态气象要素文件的数据读写与批处理实现 …

1597 - Searching the Web (UVA)

题目链接如下&#xff1a; Online Judge 我的代码如下&#xff1a; #include <iostream> #include <string> #include <vector> #include <cctype> #include <sstream> #include <map> #include <set> // #define debugstd::vect…

Techlink TL24G06 网络变压器 10G 基座单端口变压器

功能特征&#xff1a; 1、符合IEEE 802.3标准。 2、符合RoHS。 3、工作温度范围&#xff1a;0C至70C。 4、储存温度范围&#xff1a;-20C至125C。

thinkphp的自增setInc和自减setDec

// score 字段加 1 Db::table(think_user)->where(id, 1)->setInc(score); // score 字段加 5 Db::table(think_user)->where(id, 1)->setInc(score, 5); // score 字段减 1 Db::table(think_user)->where(id, 1)->setDec(score); // score 字段减 5 Db::tab…

如何使用查看器筛选、搜索功能进行数据定位?

前言 我们曾探讨过观测云如何通过将内置视图与查看器相联结&#xff0c;实现更全面的数据关联分析。&#xff08;参见《内置视图联动查看器&#xff0c;实现数据关联分析》&#xff09;这里提到的查看器&#xff0c;实际是一个功能全面且强大的数据查看分析工具。其提供多种搜…

数模竞赛那么累,究竟能给我带来什么?

国赛官网上有这么一句话&#xff1a;一次参赛&#xff0c;终生受益。 学生时代&#xff0c;我对这句话没啥感触。 因为刚开始学数模时感觉很没头绪&#xff0c;书也看不懂&#xff0c;论文也看不懂&#xff0c;看啥都看不懂。 比赛时题目看不懂&#xff0c;答案搜不到&#xf…

javaEE -14(10000字 JavaScript入门 - 1)

一&#xff1a;初始 JavaScript JavaScript (简称 JS)是世界上最流行的编程语言之一&#xff0c;它是一个脚本语言, 通过解释器运&#xff0c;主要在客户端(浏览器)上运行, 现在也可以基于 node.js 在服务器端运行. JavaScript 和 HTML 和 CSS 之间的关系&#xff1a; HTML…

MySQL多线程并发控制技巧分享

在高并发的应用场景下&#xff0c;数据库的性能瓶颈往往出现在并发读写上。为了提高数据库的并发性能&#xff0c;我们需要对MySQL的多线程进行有效的并发控制。本文将分享一些MySQL多线程并发控制的技巧&#xff0c;帮助大家更好地理解和优化MySQL的并发性能。 调整线程缓存大…