P6278 [USACO20OPEN]Haircut G
显然是要求逆序对的,这东西当然可以用树状数组求就可以了
然后呢,对于每一个点i,它为后面的点的话,那\(j>i\)的时候就会有贡献
扫就行了
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
int n;
struct hair{
int id;
ll key;
}h[100005];
ll tr[100005];
ll ans[100005];
int lowbit(int x){
return x&-x;
}
void add(int x,int k){
for(int i=x;i<=n;i+=lowbit(i)){
tr[i]+=k;
}
}
ll suf[100005];
ll query(int x){
ll ans=0;
while(x){
ans+=tr[x];
x-=lowbit(x);
}
return ans;
}
int cnt;
bool cmp(hair x,hair y){
if(x.key==y.key){
return x.id>y.id;
}else{
return x.key>y.key;
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%lld",&h[i].key);
h[i].id=i;
}
sort(h+1,h+n+1,cmp);
for(int i=1;i<=n;++i){
add(h[i].id,1);
ans[h[i].id]=query(h[i].id-1);
}
cnt=n;
ll anss=0;
for(int i=0;i<n;++i){
while(cnt>=1&&i>h[cnt].key){
anss+=ans[h[cnt].id];
cnt--;
}
cout<<anss<<endl;
}
return 0;
}