https://www.luogu.org/problem/show?pid=1908
題目描述
貓貓TOM和小老鼠JERRY最近又較量上了,但是畢竟都是成年人,他們已經不喜歡再玩那種你追我趕的游戲,現在他們喜歡玩統計。最近,TOM老貓查閱到一個人類稱之為“逆序對”的東西,這東西是這樣定義的:對於給定的一段正整數序列,逆序對就是序列中ai>aj且i<j的有序對。知道這概念后,他們就比賽誰先算出給定的一段正整數序列中逆序對的數目。
輸入輸出格式
輸入格式:
第一行,一個數n,表示序列中有n個數。
第二行n個數,表示給定的序列。
輸出格式:
給定序列中逆序對的數目。
輸入輸出樣例
輸入樣例#1:
6 5 4 2 6 3 1
輸出樣例#1:
11
說明
對於50%的數據,n≤2500
對於100%的數據,n≤40000。
將原數組離散化后,用離散后的數字當做樹狀數組的下標(可能會有很大的數),然后就是樹狀數組模板求逆序對了
沒有離散得了10分~
inline 貌似不能加速
1 #include <algorithm> 2 #include <cstdio> 3 4 #define lowbit(x) (x&(-x)) 5 6 using namespace std; 7 8 const int N(40000+15); 9 int n,x,c[N],ans; 10 struct Node 11 { 12 int num,mark; 13 }a[N]; 14 15 bool cmp(Node a,Node b) 16 { 17 return a.num>b.num; 18 } 19 20 inline void up(int x) 21 { 22 for(;x<=N;x+=lowbit(x)) c[x]++; 23 } 24 25 inline int query(int x) 26 { 27 int ret=0; 28 for(;x;x-=lowbit(x)) ret+=c[x]; 29 return ret; 30 } 31 32 int main() 33 { 34 scanf("%d",&n); 35 for(int i=1;i<=n;i++) 36 scanf("%d",&a[i].num),a[i].mark=i; 37 sort(a+1,a+n+1,cmp); 38 for(int i=1;i<=n;i++) 39 { 40 41 ans+=query(a[i].mark); 42 up(a[i].mark); 43 } 44 printf("%d",ans); 45 return 0; 46 }