題目描述
給定乙個陣列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行,每行乙個長整型範圍內的整數。
輸出格式
1247.out
乙個整數,為逆序對的數目。
輸入樣例
1247.in
5
3
1
4
5 2
輸出樣例
1247.out
4 各測試點資訊
測試點編號
測試點分數
測試點時限
測試點記憶體110
1128210
1128310
1128410
1128510
1128610
1128710
1128810
1128910
1128
1010
1128
今天在石門中學的oj上練習了用樹狀陣列求逆序對,其實方法跟
昨天測試的第三題是一樣的233
用樹狀陣列維護某個數出現的次數,即tree[i]表示i出現的次數,但這個數有可能很大啊。離散化一下就好咯。
然後從左往右每個數掃一遍,對於ai,它前面有(i-1)個數,而直接計算比ai大的數的個數顯然是比較麻煩的,不過兩個數的大小關係不就大於、等於和小於三種嘛。我們可以方便的得出小於等於ai的數的個數,再用(i-1)減去之即可。
就這麼簡單。
//樹狀陣列o(nlogn)求逆序對//by lkb 2016.8.5
#include
#include
#include
using namespace std;
#define lowbit(x) (x&(-x))
const int maxn = 1e5 + 9;
struct tnode
} a[maxn]; //離散化時用
int n;
int b[maxn]; //離散後的陣列
int tree[maxn]; //樹狀陣列
bool cmp(tnode i, tnode j)
void update(int k)
}int query(int k)
return sum;
}int main()
//離散化
sort(a + 1, a + n + 1, cmp);
int now = 0;
for(int i = 1; i <= n; i++)
long long ans = 0; //注意答案最多可能是n平方級的,要開long long
for(int i = 0; i < n; i++)
cout << ans << endl;
return 0;
}
樹狀陣列求逆序對
很久以前就學了樹狀陣列,也知道可以用來求逆序對,然而一直沒弄明白他是怎麼實現的 可能當時沒搞清楚逆序對是什麼吧。逆序對就是如果i j a i a j 這兩個就算一對逆序對,簡單來說,所有逆序對的個數和就是找每乙個數的前面有幾個比他的大的數,他們加起來的和就是逆序對的總數。知道什麼是逆序對後就好辦了,...
樹狀陣列 求逆序對
樹狀陣列可以解決線段樹能夠解決的問題,且更加節省空間。線段樹的講解 可以看這位大佬的部落格 樹狀陣列的講解 另一位大佬的部落格 這裡主要寫一下利用樹狀陣列來求解逆序對的個數。簡單來說就是一段序列裡面每個數所在位置之前的位置上比這個數大的數字個數之和。例如 1 2 3 5 4 只有 4 前面的 有乙個...
樹狀陣列求逆序對
題目 分析 計算像a,b這樣上公升的有la對,像c,d這樣下降的有lb對,ans la lb。這樣是有重複的,重複的就是a與c重合,a與d重合,b與c重合,b與d重合這四種情況。那麼減去這四種情況就ok了。可以用樹狀陣列預處理出每一位i的左邊比a i 大的有多少la,少的有多少li,右邊比a i 大...