POJ 2299 Ultra-QuickSort

這個題目的本質是求一個數組的逆序對的數量,在線性代數裏面一個求逆序對數量的方法是,每次取所有剩餘數字當中最小的數,然後數一數這個數前面有多少已經取出來的數字,即爲當前這個數字所貢獻的逆序數,所以本題就要模擬這個過程,排序之後每次取出最小的數然後開始數

但是直接的模擬會導致超時,因此採用樹狀數組對已經取出來的點的個數進行記錄,每次求和然後更新

注意用long long 存儲最後的答案

#include <iostream>
#include <memory.h>
#include <cstdio>
#include <algorithm>
using namespace std;

#define maxn 500050

struct node{
    int key,pos;
};

bool operator < (node a, node b){
    return a.key < b.key;
}

node array[maxn]={0};
int inter[maxn]={0};

long long int getsum(int i){
    long long sum = 0;
    for(;i>0;i-=i&(-i)){
        sum += inter[i];
    } 
    return sum;
}

void update(int i,int n){
    for(;i<=n;i+=i&(-i)){
        inter[i]++;
    }
}

int main(){
    int n;
    while(scanf("%d",&n),n){
        long long int sum = 0;

        memset(array,0,sizeof(array));
        memset(inter,0,sizeof(inter));

        for(int i=1;i<=n;++i){
            scanf("%d",&array[i].key);
            array[i].pos = i;
        }

        sort(array+1,array+n+1);

        for(int i=n;i>0;--i){
            sum += getsum(array[i].pos);
            update(array[i].pos,n);
        }
         printf("%lld\n",sum);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章