1. 程式人生 > 其它 >P6278 [USACO20OPEN]Haircut G

P6278 [USACO20OPEN]Haircut G

Archie

顯然是要求逆序對的,這東西當然可以用樹狀陣列求就可以了

然後呢,對於每一個點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;
}