題目鏈結
題目描述
貓貓tom和小老鼠jerry最近又較量上了,但是畢竟都是成年人,他們已經不喜歡再玩那種你追我趕的遊戲,現在他們喜歡玩統計。最近,tom老貓查閱到乙個人類稱之為「逆序對」的東西,這東西是這樣定義的:對於給定的一段正整數序列,逆序對就是序列中ai>aj且i輸入格式
第一行,乙個數n,表示序列中有n個數。
第二行n個數,表示給定的序列。序列中每個數字不超過10^9109
輸出格式
給定序列中逆序對的數目。
輸入輸出樣例輸入6
5 4 2 6 3 1
輸出11
說明/提示
對於25%的資料,n≤2500
對於50%的資料,n≤4×10^4。
對於所有資料,n≤5×10^5
請使用較快的輸入輸出
應該不會n方過50萬吧 by chen_zhe
離散化線段樹的話,寫起來比較複雜,特別是區間離散化的時候就有點麻煩,需要隔板之類的,**量比較大,但動態開點線段樹的話寫起來就非常簡潔了,不容易出錯。
我們一般的線段樹的左右兒子是rt2和rt2+1,但動態開點的話就是由動態分配編號而來的,所以我們需要記錄它的左兒子後右兒子的編號,接下來的操作就是和普通的線段樹差不多了,**中會有注釋。
ac**:
#include
using
namespace std;
#define ll long long
#define lson l,mid,tree[rt].l
#define rson mid+1,r,tree[rt].r
#define ls tree[rt].l
#define rs tree[rt].r
const
int mac=
5e5+10;
const
int inf=
1e9+5;
struct node
tree[mac*32]
;int sz=1;
//動態分配的點的最大編號
ll query
(int l,
int r,
int rt,
int l,
int r)
int mid=
(l+r)
>>1;
if(mid>=l) ans+
=query
(lson,l,r);if
(mid=query
(rson,l,r)
;return ans;
}void
update
(int l,
int r,
int&rt,
int pos)
int mid=
(l+r)
>>1;
if(mid>=pos)
update
(lson,pos)
;//注意這裡傳進去的rt是左兒子的編號
else
update
(rson,pos)
; tree[rt]
.sum=tree[ls]
.sum+tree[rs]
.sum;
}int
main()
printf (
"%lld\n"
,ans)
;return0;
}
洛谷P1908 逆序對(線段樹解法)
貓貓tom和小老鼠jerry最近又較量上了,但是畢竟都是成年人,他們已經不喜歡再玩那種你追我趕的遊戲,現在他們喜歡玩統計。最近,tom老貓查閱到乙個人類稱之為 逆序對 的東西,這東西是這樣定義的 對於給定的一段正整數序列,逆序對就是序列中ai aj且i第一行,乙個數n,表示序列中有n個數。第二行n個...
洛谷 P1908 逆序對
題目描述 貓貓tom和小老鼠jerry最近又較量上了,但是畢竟都是成年人,他們已經不喜歡再玩那種你追我趕的遊戲,現在他們喜歡玩統計。最近,tom老貓查閱到乙個人類稱之為 逆序對 的東西,這東西是這樣定義的 對於給定的一段正整數序列,逆序對就是序列中ai aj且i var i,n,t longint ...
洛谷P1908 逆序對
貓貓tom和小老鼠jerry最近又較量上了,但是畢竟都是成年人,他們已經不喜歡再玩那種你追我趕的遊戲,現在他們喜歡玩統計。最近,tom老貓查閱到乙個人類稱之為 逆序對 的東西,這東西是這樣定義的 對於給定的一段正整數序列,逆序對就是序列中ai aj且i輸入格式 第一行,乙個數n,表示序列中有n個數。...