P6278 [USACO20OPEN]Haircut G
阿新 • • 發佈:2021-07-18
顯然是要求逆序對的,這東西當然可以用樹狀陣列求就可以了
然後呢,對於每一個點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; }