求逆序 二分 樹狀陣列

2021-08-19 18:39:08 字數 1302 閱讀 2251

#include#includeusing namespace std;

int a[100001],n,temp[100001];

long long ct=0;

void merg(int first,int last)else

}//把剩下的按序放進陣列。

while(i<=mid)

while(j<=n)

for(int u=first;u<=last;u++)

a[u]=temp[u];

}void mergesort(int first,int last)

mergesort(0,n-1);

cout《我寫的二分的方法,但是會超時。。。然後看了大佬們的樹狀陣列,又複習了樹狀陣列,它是便於查詢與更新,m次更新複雜度為mlgn,時間複雜度低,效率高,c[i]的意思是它包括從i起(包括i)的lowbit(i)[i&-i],個數的和,-i表示取反加一。

大佬ac鏈結1

大佬ac鏈結2   樹狀陣列詳解

/* 用樹狀陣列求逆序數:陣列a代表數字i是否在序列中出現過,

如果陣列i已經存在於序列中,則a[i]=1,否則a[i]=0,

此時query(i)返回值為在序列中比數字i小的元素的個數,

假設序列中第i個元素的值為a,

那麼前i個元素中比i大的元素的個數為i-query(a).

*/

#include #include #define maxn 100000

using namespace std;

int n,tree[maxn];

int lowbit(int i)

void update(int i,int x)

} int query(int n)

return sum;

} int main ()

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

} return 0;

}

ps:我真的是不太明白這一句:
ans+=i-query(a);
真的不明白,query(a)表示到a為止的,不明白,再想想。。。。

明白了:

query(a)表示輸入當前的狀態時,比a小的元素的個數,那麼用i(當前計算元素所處的位置),減去小於它的元素個數,剩下的便是大於等於它的元素個數,那麼就求出了當前數的逆序,對每乙個輸入的數,做判斷。

求序列的逆序對每個數求其左邊大於它的元素的個數。該演算法的複雜度o(nlogn),對n個數進行遍歷,更新樹狀陣列複雜度為logn。

樹狀陣列求逆序數

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

樹狀陣列求逆序對

題目描述 給定乙個陣列a,它包含n個整數,分別是a 1 a 2 a n 如果存在下標i和j,使得 i j 且 a i a j 同時成立,則 i,j 就為乙個 逆序對 那麼a陣列總共有多少對不同的 逆序對 輸入格式 1247.in 第一行為n 1 n 100000 接下來是n行,每行乙個長整型範圍內的...

樹狀陣列求逆序對

很久以前就學了樹狀陣列,也知道可以用來求逆序對,然而一直沒弄明白他是怎麼實現的 可能當時沒搞清楚逆序對是什麼吧。逆序對就是如果i j a i a j 這兩個就算一對逆序對,簡單來說,所有逆序對的個數和就是找每乙個數的前面有幾個比他的大的數,他們加起來的和就是逆序對的總數。知道什麼是逆序對後就好辦了,...