5 qoj14553 序列与整数对 题解

news/2025/10/3 21:10:28/文章来源:https://www.cnblogs.com/michaele/p/19124996

序列与整数对

题面

给定一个长度为 \(n\) 的正整数序列 \(A_1, A_2, \cdots,A_n\) ,有 \(m\) 次询问,每次给定两个正整数 \(x, y\) ,求有多少个整数对 \((i,j)\) 满足 \(1 \le i < j \le n,A_i = x, A_j = y\)

\(1 \le n, m \le 10^5\)

\(1 \le A_i, x, y \le 10^9\)

题解

这道题用根号分治思想来解决。

先挑出这道题的难点,就是对于每个询问,我们无法快速找到有多少个对应的整数对。

朴素做法:先离散化,然后对每个数记录其出现位置,询问枚举 \(x/y\) 的出现位置,然后再另外一个出现位置中查找,符合条件的解,单次时间复杂度 \(O(n^2)\) ,可以用双指针优化到 \(O(n)\)。总时间复杂度 \(O(nm)\)

我们应用轻重分治思想来解决这道题。

首先我们考虑朴素解法,如果我们不进行处理,那么每次查询是 \(O(n)\) 的。

我们定义 \(B\) 表示一个分界线,如果出现次数 \(\le B\) 那么我们定义其为轻,否则为重。

对每个询问分类讨论:

  • \(x, y\) 两个都为轻

    我们枚举 \(x\) 的出现位置,然后用双指针即可实现 \(O(cnt_x + cnt_y)\),单次时间复杂度 \(O(B)\)

  • \(x, y\) 其中一个为重

    那么如果我们还是枚举,那么最坏就是 \(O(n)\) 的,所以我们将其进行预处理,对于每个出现次数 \(>B\)\(x\)

    我们预处理出 \(mp1[x][y]\) 表示询问 \((x,y)\) 的答案,\(mp2[x][y]\) 表示询问 \((y,x)\) 的答案。

    对于每个 \(x\),这两个都可以 \(O(n)\) 求,因为每个 \(cnt_x > B\) 所以这样的 \(x\) 的个数不会超过 \(\frac n B\)

    预处理时间复杂度 \(O(n \frac n B)\)

总时间复杂度 \(O(n(B + \frac n B))\)

code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
#include <cmath>using namespace std;typedef long long ll;const int N = 1e5 + 10;int n, m;
int a[N], b[N], cnt;
int sum[N];
map <pair <int, int>, ll> mp1, mp2;
vector <int> pos[N];int main () {// freopen ("test/test.in", "r", stdin);// freopen ("test/test.out", "w", stdout);cin >> n >> m;int B = sqrt (n);for (int i = 1; i <= n; i ++) {cin >> a[i];b[i] = a[i];}sort (b + 1, b + 1 + n);cnt = unique (b + 1, b + 1 + n) - 1 - b;for (int i = 1; i <= n; i ++) {a[i] = lower_bound (b + 1, b + 1 + cnt, a[i]) - b;pos[a[i]].push_back (i);}for (int i = 1; i <= cnt; i ++) {if (pos[i].size () > B) {sum[0] = 0, sum[n + 1] = 0;for (int j = 1; j <= n; j ++) {if (a[j] == i) {sum[j] = sum[j - 1] + 1;} else {sum[j] = sum[j - 1];mp1[{i, a[j]}] += sum[j];}}for (int j = n; j >= 1; j --) {if (a[j] == i) {sum[j] = sum[j + 1] + 1;} else {sum[j] = sum[j + 1];mp2[{i, a[j]}] += sum[j];}}}}for (int i = 1; i <= m; i ++) {int fx, fy, x, y;cin >> fx >> fy;x = lower_bound (b + 1, b + 1 + cnt, fx) - b;y = lower_bound (b + 1, b + 1 + cnt, fy) - b;if (b[x] != fx || b[y] != fy) {cout << 0 <<  endl;continue;}ll ans = 0;if (x == y) {ll cnt = pos[x].size ();ans = cnt * (cnt - 1) / 2;} else if (pos[x].size () <= B && pos[y].size () <= B) {int cnt1 = pos[x].size (), cnt2 = pos[y].size ();int p1 = 0, p2 = 0;for (; p1 < cnt1; p1 ++) {// 保证 y 在 x 右边while (p2 < cnt2 && pos[x][p1] >= pos[y][p2]) p2 ++;ans += cnt2 - p2;}} else {if (pos[x].size () > B) ans = mp1[{x, y}];else ans = mp2[{y, x}];}cout << ans << endl;}return 0;
}

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

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

相关文章

AT_arc064_d [ARC064F] Rotated Palindromes

比较好的题。 首先你考虑一个回文串,什么时候会循环的时候重复计算。当且仅当其有一个最小循环节 \(t\),移动 \(t\) 次后就会相同。 我们要将这种东西给减掉,同样的,这种贡献我们可以在计算长度 \(\le n\) 的回文串…

vscode代码块格式转换器

介绍 在我们使用vscode时,我们会用到代码块。 代码块十分好用,可以帮我们自动补全代码,也可以存各种板子。虽然会损失人的代码能力,但能提升做题效率。但我们注意到,vscode的代码块是使用json编辑的,对于不会jso…

C语言速成秘籍——跳转语句(goto) - 实践

C语言速成秘籍——跳转语句(goto) - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "M…

常州城乡和住房建设厅网站简述建设企业网站可信度的具体策略

作者&#xff1a;vivo 互联网服务器团队- Li Gang 本文介绍了一次排查Dubbo线程池耗尽问题的过程。通过查看Dubbo线程状态、分析Jedis连接池获取连接的源码、排查死锁条件等方面&#xff0c;最终确认是因为使用了cluster pipeline模式且没有设置超时时间导致死锁问题。 一、背…

从免疫原性突破到技术迭代:全人源抗体如何重塑靶向治疗格局?

在治疗性抗体领域,“降低免疫原性” 始终是研发的核心追求 —— 人源化抗体虽通过框架区改造将鼠源序列占比降至 5% 以下(如阿达木单抗),但临床数据显示仍有 3.2% 患者产生抗药抗体(ADA),导致药物清除率提升 50…

实用指南:OpenAI Sora 2重磅发布:AI视频生成进入“GPT-3.5时刻”

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

商业网站的规划和设计linux wordpress 升级

在C语言中&#xff0c;flock 是一个用于文件锁定的函数&#xff0c;定义在 sys/file.h 头文件中。它的主要目的是在对文件进行读写操作时&#xff0c;避免其他进程同时访问文件&#xff0c;以实现文件的并发控制。 flock 函数的原型 #include <sys/file.h>int flock(in…

无锡做网站哪家公司好延庆上海网站建设

题目大意&#xff1a; 有边权点权的树&#xff0c;动态修改点权 每次修改后求带权重心x (\(minimize\) \(S\sum_i val[i]*dist[x][i]\)) 分析&#xff1a; 从暴力找突破口&#xff1a; 对于边x,y&#xff0c;设长度为len&#xff0c;切断后x半边树权值和为\(w_1\)&#xff0c;y…

工作感受月记(202510月)

国庆节在毕节上班一天中...... 2025年10月03号 1/ 值班完成手中TODO list,icm,case,blog,和墨墨记单词270 2/ 整理心态,看queue中 今日关键字:挣钱中

域名就是网站名吗wordpress 消息推送

这里将介绍如何使用 OpenCV 与 Python 来作彩色影像转HSV(RGB to HSV 或 BGR to HSV)&#xff0c;在写 Python 影像处理程序时常会用到 OpenCV cvtColor 作颜色空间转换的功能&#xff0c;接下来介绍怎么使用 Python 搭配 OpenCV 模块来进行 RGB/BGR 转 HSV 彩色转HSV空间。 H…

欧几里得算法与扩展欧几里得算法详解

在数论和密码学中,欧几里得算法(Euclidean Algorithm)是一个古老而重要的算法,用于计算两个整数的最大公约数(GCD)。 欧几里得算法(更相减损法) 欧几里得算法基于以下原理:两个整数的最大公约数等于其中较小的…

网站承建乐山网站公众号建设

前置操作 如果是在 spring-config 中添加 bean 标签来注册内容&#xff0c;每个类都要弄一次就显得麻烦和臃肿了&#xff0c;对于 new 操作而言就没有什么优势了。因此 spring 就引入了注解操作来实现对 Bean 对象的存储。 配置扫描路径 想要将对象成功的存储到 Spring 中&…

网站建设交流发言稿如何建立网站模板

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

题解:AT_agc038_f [AGC038F] Two Permutations

题目: 置换环是显然的,一个环有旋一下和不旋两种状态。 \((P_i=i,Q_i=i,P_i=Q_i)\) 无非这三个限制。\((0,0,0)\):旋一个以上就有贡献。 \((0,0,1)\):旋一个才有贡献。 \((0,1,0)\):旋 P 才有贡献。 \((1,0,0)\):…

完整教程:flink批处理-时间和窗口

完整教程:flink批处理-时间和窗口2025-10-03 20:43 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !impo…

详细介绍:Java基础

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

10.3 考试总结

10.3 考试总结10.3 考试总结 题面下载 得分情况 悲痛爆零 时间分配(大概) 8:30 $ \ $ -- $ \ $T1第一版dp写了出来,大样例没过,开始打dfs 9:20 $ \ $ -- $ \ $T1 dfs好像过了,感觉T3更简单,想去打T3 10:10 --…

国庆集训-JDAY3

国庆集训-JDAY3T1 love思路 暴力枚举 解法 枚举天数,累加即可 归纳总结解题策略 枚举 结果 100pts 时间分配 10minT2 square思路 递推,从\(s_1\)推到\(s_n\) 解法 \(s\)每次变成\(s+n个.+s\) 归纳总结解题策略 递归/…

CSP-S 复赛指南(2025年版)

第一章 数据结构 第一节 线性结构 1.1 【5】双端栈 1.1.1 什么是双端栈? 在理解双端栈之前,我们先回顾一下普通的栈。一个普通的栈,所有元素的插入(入栈,push)和删除(出栈,pop)都只能在同一端——也就是“栈…