CF540E Infinite Inversions 题解
简要分析
求逆序对,但是元素很多(\(\le 10^9\)),由于题目给出的 \(n\) 却比较小,所以我们可以从 \(n\) 入手:
显而易见,\(10^9\) 的元素中最多只会有 \(2 \times 10^5\) 个被交换(不会重复交换一个元素),而剩下的大量数据如果都储存下来,是没有意义的。
我们可以将没有参与交换的元素中,连续的部分看成一个整体,这里就用到了离散化的思想,将这些元素合并以后,剩下的元素就可以 \(O(n \log n)\) 求逆序对了。
逆序对
逆序对怎么求,这里我们可以用树状数组求。由于这个不是模板题,不再解释。(都是紫题了还要讲逆序对?)
但是在这道题中,一部分元素是包含多个元素的,怎么办?
这就可以用到权值逆序对:我们在查找的过程中,现在发现了一个现在数组中的一对逆序对 \(p_i > p_j\)(\(i < j\)),\(p_i\) 包含 \(t_i\) 个元素,\(p_j\) 包含 \(t_j\) 个元素。因为只有连续的区间才会被合并,所以 \(p_i\) 包含的所有元素都大于 \(p_j\) 中的任意元素。
因此,\(p_i\) 和 \(p_j\) 对答案的贡献为 \(t_i \times t_j\)。
细节和易错点
-
数组别开的太小,开到 \(2 \times 10^5\) 是会 RE 的,我开到了 \(4 \times 10^5\)。
-
\(10^5\) 级别的数据,不开
long long
怎么行?
代码
(由于我大量使用了 STL,所以效率并不太高 懒 呵呵)
#include <bits/stdc++.h> #define int long long #define rr read() using namespace std; const int N = 4e5 + 10; // 快读 inline int read() { int num = 0, flag = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') flag = -1; for (; isdigit(ch); ch = getchar()) num = (num << 3) + (num << 1) + ch - '0'; return num * flag; } // 存放元素 struct node { int x, y; node() { x = y = 0; } node(int _x, int _y) { x = _x, y = _y; } bool operator<(const node &t) const { return x < t.x; } }; vector<node> q; vector<node> a; set<node> uq; set<node> ad; unordered_map<int, int> to; // 树状数组 int s[N]; inline int lobit(int x) { return x & -x; } void upd(int x, int t) { for (; x < N; x += lobit(x)) s[x] += t; } int que(int x) { int res = 0; for (; x; x -= lobit(x)) res += s[x]; return res; } signed main() { int m = rr; for (int i = 0; i < m; ++i) q.push_back({rr, rr}), uq.emplace(q[i].x, 1), uq.emplace(q[i].y, 1); // 去重和合并 set<node>::iterator _a = uq.begin(), _b(_a); for (++_b; _b != uq.end(); ++_a, ++_b) if (_a->x < _b->x - 1) ad.emplace(_b->x - 1, _b->x - _a->x - 1); uq.insert(ad.begin(), ad.end()); int n = 0; for (node i : uq) to[i.x] = n++, a.push_back({n, i.y}); // 进行交换操作 for (int i = 0; i < m; ++i) swap(a[to[q[i].x]], a[to[q[i].y]]); // 求逆序对 int ans = 0; for (int i = n - 1; i >= 0; --i) { ans += que(a[i].x - 1) * a[i].y; upd(a[i].x, a[i].y); } printf("%lld\n", ans); return 0; }
本文来自博客园,作者:RainPPR,转载请注明原文链接:https://www.cnblogs.com/RainPPR/p/solution-cf540e.html
如有侵权请联系我(或 2125773894@qq.com)删除。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!