一道逆序对题
CF1915F
https://codeforces.com/contest/1915/problem/F
先了解什么是逆序对 https://www.luogu.com.cn/problem/P1908 即i < j但a[i] > a[j]的数对。
求解的方法:树状数组求解。
树状数组维护的其实就是一个区间内比他大并且比他先出现的值,每次查询的范围就是在原数组的下标之前。
我们可以先将数组按照第一关键字为值,第二关键字为下标数从大到小排序,一是离散化处理,二是为了让值相同,下标大的先出现,这样在统计的过程中,就不会多统计。
现在回到本题。
手画一下,当一个区间[l, r], [x, y],是完全包含的关系的时候,就是一种合法的情况。先将所有l排序,这时的顺序是l从小到大的顺序,然后对该顺序下的r统计逆序对(这里面的思维有点绕,需要理清楚)
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, int> PII; const int mod = 998244353, INF = 1 << 30; const int N = 2e5 + 10; PII a[N], b[N]; LL c[N]; int n; int lowbit(int x) { return x & (-x); } void update(int p, LL k) { for (; p <= n; p += lowbit(p)) { c[p] += k; } } LL ask(int p) { LL ans = 0; while (p) { ans += c[p]; p -= lowbit(p); } return ans; } void solve() { cin >> n; vector<int> B(n + 1); for (int i = 1; i <= n; i ++) { cin >> a[i].first; a[i].second = i; cin >> B[i]; c[i] = 0; } sort(a + 1, a + 1 + n); LL ans = 0; for (int i = 1; i <= n; i ++) { b[i].first = B[a[i].second]; b[i].second = i; } sort(b + 1, b + 1 + n, greater<PII>()); for (int i = 1; i <= n; i ++) { ans += ask(b[i].second - 1); update(b[i].second, 1); } cout << ans << endl; } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); int t = 1; cin >> t; while(t --) solve(); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?