树状数组求解全局逆序对问题
基础
对于一维数组求解严格逆序对问题,需要用到一个技巧,就是把数字作为树状数组的下标,序列{5,4,2,6,3,1},对应a[5] a[4] a[2] a[6] a[3] a[1]。每处理一个数字,树状数组的下标对应的元素数值+1,统计前缀和,就是逆序对的数量。
可以逆序或者正序做,推荐逆序。
- 比如说逆序求解:
对于上面提到的序列{5,4,2,6,3,1}
数字1,把a[1]+1,计算a[1]的前缀和sum(0),逆序对数量ans=ans+sum(0)=0;
数字3,把a[3]+1,计算a[3]的前缀和sum(2),逆序对数量ans=ans+sum(2)=0;
数字6,把a[6]+1,计算a[6]的前缀和sum(5),逆序对数量ans=ans+sum(5)=0;
... - 再看看正序求解,当前已经处理的数字个数减掉当前数字的前缀和即为以该数为较小数的逆序对的个数
数字5,把a[5]+1,当前处理了1个数,ans=ans+(1-sum(5))=0;
数字4,把a[4]+1,当前处理了2个数,ans=ans+(1-sum(4))=1;
数字2,把a[2]+1,当前处理了3个数,ans=ans+(1-sum(2))=3;
...
又一个例子:
例题
- cf A. Inversions
求解数组数当前数前逆序对的个数
//>>>Qiansui #include<map> #include<set> #include<list> #include<stack> #include<cmath> #include<queue> #include<deque> #include<cstdio> #include<string> #include<vector> #include<utility> #include<iomanip> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #include<functional> #define ll long long #define ull unsigned long long #define mem(x,y) memset(x,y,sizeof(x)) //#define int long long inline ll read() { ll x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-48;ch=getchar();} return x*f; } using namespace std; typedef pair<int,int> pii; typedef pair<ll,ll> pll; typedef pair<ull,ull> pull; typedef pair<double,double> pdd; /* https://codeforces.com/edu/course/2/lesson/4/3/practice/contest/274545/problem/A */ const int maxm=1e5+5,inf=0x3f3f3f3f,mod=998244353; ll n,a[maxm],b[maxm],ans[maxm]; int lowbit(int x){return x&(-x);} void update(int x,int v){ while(x<=n){ b[x]+=v; x+=lowbit(x); } return ; } ll getsum(int x){ ll ans=0; while(x){ ans+=b[x]; x-=lowbit(x); } return ans; } void solve(){ int c=0; cin>>n; for(int i=1;i<=n;++i) cin>>a[i]; for(int i=1;i<=n;++i){//正序求解 update(a[i],1); ans[i]=c-getsum(a[i]-1);//当前已经处理的数字个数-比当前数字小的数字个数即为在当前位置前大于当前数字的数字个数 ++c; } for(int i=1;i<=n;++i){ cout<<ans[i]<<" \n"[i==n]; } return ; } signed main(){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); int _=1; // cin>>_; while(_--){ solve(); } return 0; }
相关资料
本文来自博客园,作者:Qiansui,转载请注明原文链接:https://www.cnblogs.com/Qiansui/p/17510562.html
分类:
数据结构 - 树状数组 BIT
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)