feat: 添加P5200题解实现,使用树状数组计算逆序对

实现了一个使用树状数组计算逆序对数量的算法,用于解决P5200题目。通过维护树状数组来高效计算区间和,从而确定每个元素的逆序对数量。
This commit is contained in:
Zengtudor 2025-08-31 16:17:34 +08:00
parent 8b1f7317ff
commit c5c309b935

65
src/8/31/P5200.cpp Normal file
View File

@ -0,0 +1,65 @@
#include <cstdint>
#include <iostream>
#include <istream>
#include <vector>
using ll = int64_t;
ll n;
std::vector<ll> v,t,ans;
#define pv(v)do{std::cout<<#v<<" :"<<(v)<<"\n";}while(0)
static inline constexpr ll lowbit(ll n){
return n&(-n);
}
static inline void set(ll idx,ll addval){
while(idx<=n){
t[idx]+=addval;
idx+=lowbit(idx);
}
}
static inline ll getsfx(ll idx){
ll res=0;
while(idx){
res+=t[idx];
idx-=lowbit(idx);
}
return res;
}
static inline ll getrange(ll l,ll r){
return getsfx(r)-getsfx(l-1);
}
int main(){
std::iostream::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin>>n;
v.resize(n+1);
t.resize(n+1);
ans.reserve(n+1);
for(ll i=1;i<=n;++i){
std::cin>>v[i];
}
ll idx=n;
for(;idx>=2 && v[idx-1]<=v[idx];--idx);
// pv(idx);
for(ll i=idx;i<=n;i++){
set(v[i], 1);
}
ll sum=0;
for(ll i=1;i<idx;i++){
ll add = idx-i-1 + getrange(1, v[i]);
sum+=add;
ans.push_back(add);
set(v[i], 1);
}
std::cout<<idx-1<<"\n";
for(ll i:ans){
std::cout<<i<<" ";
}
std::cout<<"\n";
}