求逆序对
1.归并排序求逆序对
归并排序,只加了一行res+=mid-i+1;
递归里面运行完两个mergeSort后,start~mid 和 mid+1~end都是有序的,且两个内部的逆序对都已经算过了,只需要算当前状态的逆序对就行了,不会重复的

class Solution { public: int merge(vector<int> &nums,int l,int r) { if(l>=r) return 0; //只有一个元素 int mid=(l+r)>>1; //二分 int res=merge(nums,l,mid)+merge(nums,mid+1,r); //计算左右两个区间中的逆序对 int i=l,j=mid+1; //定义两个指针 vector<int> temp; while(i<=mid&&j<=r) //归并 { if(nums[i]<=nums[j]) temp.push_back(nums[i++]); else { temp.push_back(nums[j++]); //后面的元素小于前面的元素 res+=mid-i+1; } } //无论是i或者是j,元素都比之前的数组要大,所以不可能存在新的逆序,把数组填好就可以了 while(i<=mid) temp.push_back(nums[i++]); while(j<=r) temp.push_back(nums[j++]); i=l; for(auto x:temp) nums[i++]=x; return res; } int inversePairs(vector<int>& nums) { return merge(nums,0,nums.size()-1); } }; 作者:无忧 链接:https://www.acwing.com/solution/content/2085/ 来源:AcWing 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2.树状数组求逆序对
①离散化,可利用排序规则
②树状数组求解,边插入边求解

#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5 + 5; int a[N]; int d[N]; int t[N]; int n; int lowbit(int x) { return x & (-x); } ll getsum(int x) { ll sum = 0; for (ll i = x; i; i -= lowbit(i)) { sum += t[i]; } return sum; } int update(int x) { for (x; x <= n; x += lowbit(x)) { t[x] += 1; } } bool cmp(int x, int y) { if (a[x] == a[y]) { return x > y; } return a[x] > a[y]; } int main() { cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; d[i] = i; } sort(d + 1, d + 1 + n, cmp); ll sum = 0; for (int i = 1; i <= n; i++) { update(d[i]); sum += getsum(d[i]-1); } cout << sum << endl; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧