mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-08-31 23:41:41 +00:00
feat: 添加P5200题解实现,使用树状数组计算逆序对
实现了一个使用树状数组计算逆序对数量的算法,用于解决P5200题目。通过维护树状数组来高效计算区间和,从而确定每个元素的逆序对数量。
This commit is contained in:
parent
8b1f7317ff
commit
c5c309b935
65
src/8/31/P5200.cpp
Normal file
65
src/8/31/P5200.cpp
Normal 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";
|
||||
}
|
Loading…
Reference in New Issue
Block a user