D. Friends and Subsequences Codeforces Round #361 (Div. 2)RMQ+二分 单调队列

news2024/11/16 8:47:43

题目传送门

题意为 给定两个长度为n的数组,设为a数组和b数组,需要找到所有可能的区间中,a数组的最大值等于b数组的最小值的个数。

1:RMQ + 二分

RMQ 能找到一个数组在任意区间的最大值或者最小值,只需要在O(n)的时间复杂度下就能完成预处理
紧接着想到单调性:枚举左端点,也就是先确定好左端点,右端点从左往右,a数组的最大值一定是在增大或者不变,b数组的最小值一定也是在减小或者不变,那么这样就有了单调性,联想到二分
在这里插入图片描述
我们只需要二分出来这两个端点,然后算出中间长度,再累加就可以得到我们的答案了

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
const int N = 2e5 + 10, M = 18;
int mx[N][M], mn[N][M], a[N], b[N];
int n;
void init()
{
    for (int i = n ;i>=1;i--)
    {
        for (int j = 0; j <= 17; j++)
        {
            if (i + (1 << j) - 1 > n) break;
            if (!j) mx[i][j] = a[i];
            else mx[i][j] = max(mx[i][j - 1], mx[i + (1 << j - 1)][j - 1]);
        }
    }
    for (int i = n; i >= 1; i--)
    {
        for (int j = 0; j <= 17; j++)
        {
            if (i + (1 << j) - 1 > n) break;
            if (!j) mn[i][j] = b[i];
            else mn[i][j] = min(mn[i][j - 1], mn[i + (1 << j - 1)][j - 1]);
        }
    }
}
int query_max(int l, int r)
{
    int len = r - l + 1;
    int tmp = log(len) / log(2);
    return max(mx[l][tmp], mx[r - (1<<tmp) + 1][tmp]);
}
int query_min(int l, int r)
{
    int len = r - l + 1;
    int tmp = log(len) / log(2);
    return min(mn[l][tmp], mn[r - (1 << tmp) + 1][tmp]);
}
bool check1(int l,int r)
{
    int x = query_max(l, r);
    int y = query_min(l, r);
    if (x >= y)return 1;
    else return 0;
}
bool check2(int l, int r)
{
    int x = query_max(l, r);
    int y = query_min(l, r);
    if (x > y)return 1;
    else return 0;
}
void solve()
{
    ll ans = 0;
    for (int i = 1;i <= n; i++)
    {
        int l = i, r = n;
        while (l < r)
        {
            int mid = l + r >> 1;
            if (check1(i,mid)) r = mid;
            else l = mid + 1;
        }
        if (query_max(i, l) == query_min(i, l))
        {
            int t = l;
            int r = n;
            while (l < r)
            {
                int mid = l + r >> 1;
                if (check2(i, mid)) r = mid;
                else l = mid + 1;
            }
            if(l==n && query_max(i,l) == query_min(i,n)) l++; //这里如果按照我这样二分的话
            //要加个特判,因为我这里二分是找到第一个query_max(i,l) > query_min(i,n) 的数
            //可是如果找不到的话,就会返回n,这样的话就要l++,取到n+1
            ans += (ll)l - t;
        }
        
    }
    cout << ans << endl;
}
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= n; i++) cin >> b[i];
    init();//RMQ预处理
    solve();
    return 0;
}

2:单调队列:

我们还可以采取前后单调队列的方法来做,这里我们枚举终点,做两个单调队列
一个单调队列记录a数组最大值下标,一个记录b数组最小值下标(队列里的第一个数就是该值的下标)
我们需要找到第a数组最大值与b数组最小值相等,也就是我们要从队列从前往后丢数出去,丢到队列1的最大值<=队列2的最小值为止。
如果实行呢?我们用一个 j 从 j 到 i 枚举,并且同时判断最大值和最小值的情况就可以了
这里要理解的是j是一步一步从左往右枚举,但是队列因为存储的是下标所以是跳着进行的
到最后满足条件的时候队列1的第一个值的下标和队列2的第一个值的下标距离 j 会有一段距离
而这二者的距离的min值就是我们需要进行累加的答案。
这里其实也满足单调性,每组数据一定只能找得到一次最大值和最小值相等,对于重复情况只需要在建立单调队列的时候只记录到最后一个值的下标就好了。

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
#define ll long long 
const int N = 2e5 + 10;
int a[N];
int b[N];
int q1[N], q2[N];
void solve()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i];
	for (int i = 1; i <= n; i++) cin >> b[i];
	int h1 = 1, h2 = 1, t1 = 0, t2 = 0;
	ll ans = 0;
	for (int i = 1,j = 1; i <= n; i++)
	{
		while (h1 <= t1 && a[i] >= a[q1[t1]]) t1--;
		while (h2 <= t2 && b[i] <= b[q2[t2]]) t2--;
		q1[++t1] = i, q2[++t2] = i;
		while (j <= i && a[q1[h1]] > b[q2[h2]])
		{
			j++;
			if(h1 <= t1 && q1[h1] < j) h1++;
			if(h2 <= t2 && q2[h2] < j) h2++;
		}
		if (h1<=t1 && h2<=t2 && a[q1[h1]] == b[q2[h2]]) ans +=(ll) min(q1[h1], q2[h2]) - j + 1;
	}
	cout << ans << endl;
}
int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int T;
	//cin >> T;
	T = 1;
	while (T--)
	{
		solve();
	}
	return 0;
}

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

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

相关文章

【Java基础知识复盘】HashMap篇——持续更新中

本人知识复盘系列的博客并非全部原创&#xff0c;大部分摘自网络&#xff0c;只是为了记录在自己的博客方便查阅&#xff0c;往后也会陆续在本篇博客更新本人查阅到的新的知识点&#xff0c;望悉知&#xff01; HashMap 概述 HashMap 是一个散列表&#xff0c;它存储的内容是…

hashMap相关

文章目录HashMapHashMap介绍HashMap在 JDK1.7和 JDK1.8中的区别JDK1.7中HashMap头插法死循环的原因HashMap的底层原理HashMap的扩容机制解决Hash冲突的方法为什么在解决hash冲突的时候选择先用链表&#xff0c;再转红黑树?HashMap为什么线程不安全一般用什么作为HashMap的key?…

程序员需要达到什么水平才能顺利拿到 20k 无压力?

很有趣的是&#xff0c;在程序员身上&#xff0c;我看到了最明显&#xff0c;也最有趣的贫富差距。 根据2022最新版大厂新入职员工职级对应表&#xff0c;大厂技术线的员工轻而易举地拿到了20w的水平&#xff0c;而只要往上够一够&#xff0c;30w也不是什么难事。 然而&#xf…

玩转云服务器:怎样用云服务器架设大型3D魔幻手游【魔域】服务器,实现联机多人同玩,带你一起搞机,了解游戏搭建过程,详细教程

准备工作&#xff1a; 你首先要准备一台云服务器&#xff01; 服务器配置&#xff1a;2核4G以上配置&#xff01; 服务器系统&#xff1a;win2012 开始搭建&#xff1a; 下载游戏服务端&#xff08;有些多人叫源码&#xff0c;这里我就不解释了&#xff0c;喜欢怎么叫就怎…

SpringCloud Alibaba | 网关(三) : SpringCloudGateway 过滤器获取application/json中body数据

SpringCloudGateway 过滤器获取application/json中body数据一、前言二、通过cachedRequestBodyObject缓存获取三、ServerHttpRequest getBody方法获取四、(*&#xffe3;︶&#xffe3;)一、前言 项目接口需要加解密,就在网关层进行解密操作。那么问题来了怎么在gateway 的filt…

基于松鼠算法改进的DELM预测-附代码

松鼠算法改进的深度极限学习机DELM的回归预测 文章目录松鼠算法改进的深度极限学习机DELM的回归预测1.ELM原理2.深度极限学习机&#xff08;DELM&#xff09;原理3.松鼠算法4.松鼠算法改进DELM5.实验结果6.参考文献7.Matlab代码1.ELM原理 ELM基础原理请参考&#xff1a;https:…

线程池相关

文章目录为什么需要线程池&#xff1f;池化思想常用方法execute()方法submit()方法shutdownisShutdownisTerminatedawaitTerminationshutdownNow创建线程池 七个参数流程JAVA线程池有哪几种类型?线程池常用的阻塞队列有哪些?源码中线程池是怎么复用线程的?如何合理配置线程池…

EMQX Cloud 自定义函数实现多种 IoT 数据形式的灵活转化

物联网场景中&#xff0c;各类设备终端的种类繁杂&#xff0c;所使用的通信协议各异&#xff0c;从而使得应用层的数据格式也各不相同。为了帮助用户实现统一数据格式&#xff0c;EMQX Cloud 最近推出了自定义函数功能&#xff1a;根据用户自定义的脚本对设备上报的数据进行预处…

上美股份在港交所上市:预计全年利润下滑,一叶子收入持续走低

12月22日&#xff0c;上海上美化妆品股份有限公司&#xff08;HK:02145&#xff0c;下称“上美股份”&#xff09;在港交所上市。本次上市&#xff0c;上美股份的发行价格为25.20港元/股&#xff0c;为此前发行区间的最低值。据此计算&#xff0c;上美股份的募资总额约为9.31亿…

CDH6.3.2集成Apache Atlas2.1.0

1 环境准备 1.1 CDH6.3.2 环境搭建 参考文档如下 Cloudera Manager安装CDH6教程-&#xff08;一&#xff09;虚拟环境安装配置 Cloudera Manager安装CDH6教程-&#xff08;二&#xff09;搭建Cloudera和CDH6 CM和CDH在安装的时候遇到的问题 CDH6.3.2 各组件版本 1.2 apa…

火爆“有机新消费”驶入酱油赛道 好记打造我国有机酱油行业领导品牌

根据观研报告网发布的《2022年中国有机酱油市场分析报告-市场竞争策略与发展动向前瞻》显示&#xff0c;有机酱油是指采用有机农作物为原料酿制的酱油。有机酱油含有浓郁的酱香和脂香&#xff0c;是一种不可多得的上等调味品&#xff0c;适合于蘸食&#xff0c;红烧&#xff0c…

以技术创新践行社会责任,欧科云链斩获界面新闻年度双项大奖

12月20日&#xff0c;欧科云链凭借在区块链技术领域的创新&#xff0c;与腾讯、宁德时代和埃森哲等各领域领先企业一同荣获“2022好公司行业领先大奖”。 12月21日&#xff0c;欧科云链以区块链科技之力积极践行社会责任&#xff0c;绽放商业向善的力量&#xff0c;与茅台、蚂蚁…

华为云Stack智能进化,三大举措赋能政企深度用云

【中国&#xff0c;深圳&#xff0c;2022年12月22日】今天&#xff0c;以“政企深度用云&#xff0c;释放数字生产力”为主题的华为云Stack战略暨新品发布会在线上举办&#xff0c;华为云围绕“让技术不难用、让场景变简单、让经验可复制”提出三大关键举措赋能政企迈向深度用云…

无线鼠标怎么连接电脑?2个方法,轻松学会

现在越来越多的小伙伴都喜欢使用无线鼠标。相比于有线鼠标&#xff0c;无线鼠标方便快捷&#xff0c;不会受到USB线的束缚。可是很多小伙伴买回无线鼠标&#xff0c;第一次使用的时候&#xff0c;却发现自己不知道怎么使用。无线鼠标怎么连接电脑&#xff1f;今天小编给大家带来…

对于转行Pyhon程序员,这些是我们需要知道的事情..

不知道从什么时候开始&#xff0c;我们焦虑当下&#xff0c;担心未来&#xff0c;踌躇和迷茫甚至痛苦成为我们的“生活伴侣”。 我无法定义这是好是坏&#xff0c;但我知道这肯定很难受。于是乎总很多人想寻得一个答案&#xff0c;希望可以抹平心中的波澜。而往往事与愿违。 …

口罩后,那些被“优化”的程序员都去哪儿了?

程序员在35岁真的会被裁吗&#xff1f; 被裁之后去哪儿工作 &#xff0c;怎么办啊&#xff1f; 在很多社交平台&#xff0c;经常能看到不少小伙伴问出这样的问题&#xff0c;既迷茫&#xff0c;又慌张。有人说自己25岁就已经被裁了&#xff0c;也有人说做程序员&#xff0c;3…

江苏移动MGV3000-YS(S)/YS(M)-S905L3卡刷和线刷固件包

江苏移动MGV3000-YS(S)&#xff0f;YS(M)-S905L3卡刷和线刷固件包 固件特点&#xff1a; 1、修改dns&#xff0c;三网通用&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、无开机广告&#xff0c;无系统更新&#xff0c;不在被强制升级&#xff1b…

数据结构与算法java实战篇--链表

目录 一.链结点 二.单链表 1.单链表的插入方法insertFirst() 2.单链表的删除方法deleteFirst() 3.链表显示displayList() 4.单链表代码&#xff1a; 三. 查找和删除指定链结点 四.双端链表 五.用链表实现的栈 六.用链表实现队列 七.有序链表 八.双向链表 1.遍历 2.插入…

“量子深度学习的春天是否已来?” | CNCC论坛分享

2022年12月8日举办的CNCC2022“量子深度学习的春天是否已来&#xff1f;”技术论坛&#xff0c;从学术、技术和产业的角度出发&#xff0c;深入探讨未来5到10年深度学习发展在算力方面的瓶颈问题、量子深度学习会给AI领域带来何种演变以及量子深度学习的技术落地是否依然久远等…

代码随想录Day58|739. 每日温度、496.下一个更大元素 I

文章目录739.每日温度496.下一个更大元素 I739.每日温度 文章讲解&#xff1a;代码随想录 (programmercarl.com) 题目链接&#xff1a;739. 每日温度 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 请根据每日 气温 列表&#xff0c;重新生成一个列表。对应位置…