今天上午,我完成了樹狀陣列求逆序對[1]的學習,並完成了luogu1908的程式設計與除錯,以下是一些記錄與感想:
樹狀陣列求逆序對的中心思想是:
1、樹狀陣列c[a[i]]記錄a[i]出現的次數,然後利用樹狀陣列求小於a[i]的數的個數s[i][2]。
2、用i - s[i]表示輸入到當前時,大於a[i]的數的個數(即關於a[i]的逆序對的個數)。
以下是我的**:
1//由於我們可以把s[i]直接累加到ans中,故不需要開s陣列2//
<&x>為跳轉符3//
以下是未離散化**4//
以下是c++**
56 #include7
8int a[40006];9
//由於題目沒有說明a[i]的最大值(只說是正整數),故將c陣列範圍往大的開
10//
max為a[i]最大值
11int c[5000000] = , n, ans(0), max(0
);12
13void add_c(int x); //
更新c陣列
14int sum(int x); //
求小於a[i]的數的個數
15int lowbit(const
int &x);
1617
intmain()
1825
//與以往**不同,本次我將處理放在讀入的迴圈之後
26//
這是因為a[i]的範圍不確定,在<&x>處迴圈到5000000太耗時間
27for(int i = 1; i <= n; ++i)
2832 printf("
%d\n
", ans);33}
3435
void add_c(int
x)3642}
4344
int sum(int
x)45
52return
s;53}54
55int lowbit(const
int &x)
56
根據注釋[1]鏈結的內容,我又做了乙份離散化版本。但尷尬的的是,對這題來說,離散化後**又長速度又慢……(所用時間是未離散化的兩倍,不過能過就是了……)
1//以下是加入離散化的**,離散化部分從<&beg>到<&end>,其餘部分有較小規模改動2//
以下是c++**
34 #include5 #include6
7struct
map__
8a[40006
];11
int c[5000000] = , n, ans(0), p(0);//
p:離散化目標最大值(max(to))
1213
//cmp1與cmp2分別用於in與po的sort排序
14 inline bool cmp1(const map__ &a, const map__ &b);
15 inline bool cmp2(const map__ &a, const map__ &b);
16void add_c(int
x);17
int sum(int
x);18
int lowbit(const
int &x);
1920
intmain()
2128
//<&beg>
29 std::sort(a + 1, a + n + 1
, cmp1);
30for(int i = 1; i <= n; ++i)
3135 std::sort(a + 1, a + n + 1
, cmp2);
36//
<&end>
37for(int i = 1; i <= n; ++i)
3842 printf("
%d\n
", ans);43}
4445 inline bool cmp1(const map__ &a, const map__ &b)
4649
50 inline bool cmp2(const map__ &a, const map__ &b)
5154
55void add_c(int
x)5662}
6364
int sum(int
x)65
72return
s;73}74
75int lowbit(const
int &x)
76
注意:由於本人也是第一次接觸離散化,而且只是嘗試按照自己理解編,所以離散化部分應該可以大幅優化,歡迎看到這篇文章的dalao指點一二。
感想:個人感覺,其實只要把問題轉化為「求從開始輸入到當前,比當前這個數更大的數的個數,最後將結果累加」之後,剩下的程式設計實現就異常簡單了(當然,前提是學會使用樹狀陣列)。
注釋:
[1]:樹狀陣列求逆序對:
樹狀陣列求逆序對
題目描述 給定乙個陣列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 這兩個就算一對逆序對,簡單來說,所有逆序對的個數和就是找每乙個數的前面有幾個比他的大的數,他們加起來的和就是逆序對的總數。知道什麼是逆序對後就好辦了,...
樹狀陣列 求逆序對
樹狀陣列可以解決線段樹能夠解決的問題,且更加節省空間。線段樹的講解 可以看這位大佬的部落格 樹狀陣列的講解 另一位大佬的部落格 這裡主要寫一下利用樹狀陣列來求解逆序對的個數。簡單來說就是一段序列裡面每個數所在位置之前的位置上比這個數大的數字個數之和。例如 1 2 3 5 4 只有 4 前面的 有乙個...