cf1268C——线段树,逆序对

/*
结果肯定和 逆序对数量有关,假设当前求第k个答案:
    如果1-k元素连续,则只要求出1-k的逆序对个数即可
    如果不连续,那么先把这k个元素移动到一起,然后再求逆序对
        移动的策略是二分找中间位置p,p左边的元素数量=p右边的元素数量 

所以用线段树去维护当前已经存在的点位置
    每次求答案:二分找位置p,求最小移动代价,求逆序对 
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 200005

int n;
struct Node{
    int pos,v;
}p[N];
int cmp(Node &a, Node & b){return a.v<b.v;}

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
ll sum1[N<<2],sum2[N<<2];
void update(int pos,int l,int r,int rt){
    if(l==r){sum1[rt]=1;sum2[rt]=l;return;}
    int m=l+r>>1;
    if(pos<=m)update(pos,lson);
    else update(pos,rson);
    sum1[rt]=sum1[rt<<1]+sum1[rt<<1|1];
    sum2[rt]=sum2[rt<<1]+sum2[rt<<1|1];
}
ll query1(int L,int R,int l,int r,int rt){
    if(L>R)return 0;
    if(L<=l && R>=r)return sum1[rt];
    int m=l+r>>1;
    ll res=0;
    if(L<=m)res+=query1(L,R,lson);
    if(R>m)res+=query1(L,R,rson);
    return res;
}
ll query2(int L,int R,int l,int r,int rt){
    if(L>R)return 0;
    if(L<=l && R>=r)return sum2[rt];
    int m=l+r>>1;
    ll res=0;
    if(L<=m)res+=query2(L,R,lson);
    if(R>m)res+=query2(L,R,rson);
    return res;
}
int query(int k,int l,int r,int rt){
    if(l==r)return l;
    int m=l+r>>1;
    if(k<=sum1[rt<<1])return query(k,lson);
    else return query(k-sum1[rt<<1],rson);
}


int main(){
    cin>>n;
    for(int i=1;i<=n;i++)scanf("%d",&p[i].v),p[i].pos=i;
    sort(p+1,p+1+n,cmp);
    
    ll rev=0; 
    for(int i=1;i<=n;i++){
        update(p[i].pos,1,n,1);
        
        //二分找到第一个中点 
        int ans=query(i/2+i%2,1,n,1); 
        
        ll Sum1=query2(1,ans-1,1,n,1);//ans前面的和 
        ll Sum2=query2(ans+1,n,1,n,1);//ans后面的和 
        ll cnt1=query1(1,ans-1,1,n,1);//ans前面个数 
        ll cnt2=query1(ans+1,n,1,n,1);//ans后面个数 
        
        ll cost=(Sum2-ans*cnt2)+(ans*cnt1-Sum1);
        if (cnt2)cost-=cnt2*(cnt2+1)/2;
        if (cnt1)cost-=(cnt1+1)*cnt1/2;
         
        rev+=query1(p[i].pos+1,n,1,n,1);
        cout<<cost+rev<<" ";
    }
    puts("");
} 

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/12132787.html