ultra-quicksort
剛剛學線性代數學到的逆序數,用多重迴圈果然超時,剛開始的時候完全沒有線段樹的思路,後來看了別人的思路,發現真的妙啊,開心的飛起來,雖然我後面又因為把小括號寫成中括號的問題wa了一晚上。比如說9 1 0 5 4這個序列,我們記錄一下他們的序號位置,然後再排個序:01
459在原序列中的位置32
541開始我們把每個節點的數值都設定為1;
我們從最小數0開始看,他原來的位置是3,說明它前面比它大的有兩個數,我們查詢從1到(位置-1),也就是1到2,查詢這段區間的總和為2;然後我們把這個位置的和-1,再依次往後看次小數。我們把所有查詢的數字加起來就是總的逆序數了。
#include
#include
#include
#include
using namespace std;
const
int inf=
0x3f3f3f3f
;const
int maxn=
500001
;int addmark[maxn<<2]
,seqtree[maxn<<2]
;struct nodea[maxn]
;int
cmp(node a,node b)
void
maketree
(int node,
int begin,
int end)
int mid=
(begin+end)/2
;maketree
(node<<
1,begin,mid)
;maketree
(node<<1|
1,mid+
1,end)
; seqtree[node]
=seqtree[node<<1]
+seqtree[node<<1|
1];}
void
update
(int node,
int begin,
int end,
int pos,
int grade)
int mid=
(begin+end)/2
;update
(node<<
1,begin,mid,pos,grade)
;update
(node<<1|
1,mid+
1,end,pos,grade)
; seqtree[node]
=seqtree[node<<1]
+seqtree[node<<1|
1];}
intquery
(int node,
int begin,
int end,
int l,
int r)
intmain()
sort
(a+1
,a+n+
1,cmp)
;for
(i=1
;i<=n;i++
) cout<}}
歸併排序需要來回不斷交換區間內的元素,我們只需要記錄k指標和j指標兩者的差值,就是在此段區間內比j指向的這個數大的數的個數,我們把這個值累加就可以。
#include
#include
#include
#include
using namespace std;
int a[
500010
],b[
500010];
long
long sum;
void
mergei
(int a,
int low,
int mid,
int high)
else
}while
(i<=mid)
b[k++
]=a[i++];
while
(j<=high)
b[k++
]=a[j++];
for(i=low;i<=high;i++
) a[i]
=b[i];}
void
merge_sort
(int a,
int low,
int high)
}int
main()
merge_sort
(a,1
,n);
cout<}}
樹狀陣列充分利用二進位制的特點組成,每次查詢i可以查詢出前i項的和,我們的思路是先把輸入的資料離散化一下,然後以離散後的資料進行更新和查詢,我們要查詢出當前數字前面有幾個比他大的數字,我們可以反著求,用前面的數字個數-比當前數字小的個數。而這個小的個數就是用樹狀陣列的查詢,開始時,我們把tree陣列初始化為0,每當查詢完畢乙個數,我們就把tree[這個數]加一,這樣我們只需要看看當前數字前面總共有多少個1就行了。
#include
#include
#include
#include
using namespace std;
int tree[
500001
],n;
struct nodea[
500001];
intlowbit
(int x)
void
update
(int x,
int k)
}int
query
(int x)
return sum;
}int
cmp(node a,node b)
intcmp1
(node a,node b)
intmain()
sort
(a+1
,a+n+
1,cmp)
;for
(i=1
;i<=n;i++
)sort
(a+1
,a+n+
1,cmp1)
;for
(i=1
;i<=n;i++
) cout<}}
poj 2299 樹狀陣列
題目大意 本題要用到樹狀陣列的離散化處理,因為資料太大 1 999999999 但還是wa了兩次,c i 的範圍計算錯誤,要用到long long 從後向前處理,每次處理乙個數,求比這個數小的個數。poj 2299 樹狀陣列 include include include include inclu...
POJ 2299(樹狀陣列,離散化)
題意 求逆序數 題解 可以將數字插入樹狀陣列,每次統計比單前數字小的個數,我們將每個數字的權值設定為1,那麼只要求在他前面數字的和就知道了,對應的逆序數格個數是i sum a i 這裡使用樹狀 陣列維護區間和 這一題由於數字範圍過大,記憶體無法承受如此大的空間,我們可以看到n最多才5e5,所以最多有...
poj 2299 樹狀陣列 離散化
樹狀陣列求逆序數 離散化 求逆序數時,加入當前數字,然後統計大於當前數字的數字個數,題目資料很大,需先將其離散化。include include include define n 500005 define lowbit x x x using namespace std int c n a n s...