線段樹或樹狀陣列求逆序數

2021-06-14 22:35:55 字數 2091 閱讀 3311

線段樹或樹狀陣列求逆序數

求逆序數的方法有分治,歸併,本文只介紹線段樹或樹狀陣列求逆序數的辦法,眾所周知,線段樹和樹狀樹可以用來解決區間操作問題,就是因為這兩個演算法區間操作的時間複雜度很低o(logn),才讓這種方法具有可行性。

首先先來看乙個序列   6 1 2 7 3 4 8 5,此序列的逆序數為5+3+1=9。冒泡法可以直接列舉出逆序數,但是時間複雜度太高o(n^2)。氣泡排序的原理是列舉每乙個陣列,然後找出這個數後面有多少個數是小於這個數的,小於它逆序數+1。仔細想一下,如果我們不用列舉這個數後面的所有數,而是直接得到小於這個數的個數,那麼效率將會大大提高。          

總共有n個數,如何判斷第i+1個數到最後乙個數之間有多少個數小於第i個數呢?不妨假設有乙個區間 [1,n],只需要判斷區間[i+1,n]之間有多少個數小於第i個數。如果我們把總區間初始化為0,然後把第i個數之前出現過的數都在相應的區間把它的值定為1,那麼問題就轉換成了[i+1,n]值的總和。再仔細想一下,區間[1,i]的值+區間[i+1,n]的值=區間[1,n]的值(i已經標記為1),所以區間[i+1,n]值的總和等於n-[1,i]的值!因為總共有n個數,不是比它小就是比它(大或等於)。

現在問題已經轉化成了區間問題,列舉每個數,然後查詢這個數前面的區間值的總和,i-[1,i]既為逆序數。

線段樹預處理時間複雜度o(nlogn),n次查詢和n次插入的時間複雜度都為o(nlogn),總的時間複雜度o(3*nlogn)

樹狀陣列不用預處理,n次查詢和n次插入的時間複雜度都為o(nlogn),總的時間複雜度o(2*nlogn)

線段樹:

// 線段樹

#include #include #include #define max 51000

#define mid(a,b) (a+b)>>1

#define r(a) (a<<1|1)

#define l(a) a<<1

typedef struct node;

int ans[max];

node tree[max<<2];

int n;

void build(int t,int l,int r) //以1為根節點建立線段樹

mid=mid(tree[t].left,tree[t].right);

build(l(t),l,mid);

build(r(t),mid+1,r);

}void insert(int t,int l,int r,int x) //向以1為根節點的區間[l,r]插入數字1

mid=mid(tree[t].left,tree[t].right);

if(l>mid)

else if(r<=mid)

else

tree[t].num=tree[l(t)].num+tree[r(t)].num;

}int query(int t,int l,int r) //查詢以1為根節點,區間[l,r]的和

else if(r<=mid)

else

}int main()

for(i=1,k=0;i<=n;i++)

printf("%lld\n",k);

}return 0;

}

樹狀陣列:

// 樹狀陣列

#include #include #include #include using namespace std;

#define max 100010

int c[max],a[max],ans[max],n;

int lowbit(int x) //返回二進位制最後乙個1所表示的數

void updata(int x) //向前更新

}int sum(int x) //向後更新求和

return sum;

}int main()

memset(c,0,sizeof(c)); //初始化樹狀陣列

for(i=1,k=0;i<=n;i++)

printf("%d\n",k);

} return 0;

}

線段樹或樹狀陣列求逆序數

線段樹或樹狀陣列求逆序數 求逆序數的方法有分治,歸併,本文只介紹線段樹或樹狀陣列求逆序數的辦法,眾所周知,線段樹和樹狀樹可以用來解決區間操作問題,就是因為這兩個演算法區間操作的時間複雜度很低o logn 才讓這種方法具有可行性。首先先來看乙個序列 6 1 2 7 3 4 8 5,此序列的逆序數為5 ...

樹狀陣列求逆序數

逆序數就是數中各位在它前面有多少個數比它大,求出這些元素個數之和。今天看了個樹狀陣列,可以很好的解決這個問題,普通方法需要o n 2 複雜度,用樹狀陣列只需要o nlongn 樹狀陣列實際上還是乙個陣列,只不過它的每個元素儲存了跟原來陣列的一些元素相關的結合值。若a為原陣列,定義陣列c為樹狀陣列。c...

樹狀陣列求逆序數

chikachika說希望和我一起做學園偶像的時候,我真的很開心。watanabeyouwatanabeyou 曜是千歌的青梅竹馬,但是aqoursaqours成立以後,千歌似乎總是與梨子在一起,而把曜冷落了。為了讓千歌知曉自己的心意,曜醬決定做一件大事!她決定把乙個給定的11 nn的排列 1 ai...