#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define ll long long
#define maxn 100005
using namespace std;
int c[maxn],n;
int low_bit(int i)
{
return i&(-i);
}
void update(int i,int v)
{
while(i<=n){
c[i]+=v;
i+=low_bit(i);
}
}
int getsum(int i)
{
int res=0;
while(i){
res+=c[i];
i-=low_bit(i);
}
return res;
}
int main()
{
// 5
// 5 3 4 2 1
while(scanf("%d",&n),n)
{
memset(c,0,sizeof(c));
int ans=0;
for(int i=1;i<=n;i++)
{
int a;
scanf("%d",&a);
update(a,1);//向上更新:因为树状数组维护的是比当前值a小的数的个数 当前输入a 比a大的值后面就更新加1 update是向上更新
int ttt = getsum(a);
ans+=i-ttt;//求逆序 已经有i个数了 减去这i个数比a小的数的个数(树状数组维护的值)
}
for(int j=0;j<n;j++){
cout<<c[j]<<" ";
}
cout<<endl;
printf("%d
",ans);
}
return 0;
}
几道例题:
蓝桥杯 小朋友排队(树状数组+逆序数)
Problem - 4911 (树状数组+离散化)
牛客多校算法A 裸题:https://ac.nowcoder.com/acm/contest/77/A