題目描述 Description
hzwer在研究逆序對。
對於數列{a},如果有序數對(I,j)滿足:i<j,a[i]>a[j],則(i,j)是一對逆序對。
給定一個數列{a},求逆序對個數。
輸入資料較大,請使用scanf代替cin讀入。
*為防卡評測,時限調低至1s
輸入描述 Input Description
第一行一個數n,表示{a}有n個元素。
接下來n個數,描述{a}。
輸出描述 Output Description
一個數,表示逆序對個數。
樣例輸入 Sample Input
5
3 1 5 2 4
樣例輸出 Sample Output
4
資料範圍及提示 Data Size & Hint
對於10%資料,1<=n<=100.
對於20%資料,1<=n<=10000.
對於30%資料,1<=n<=100000.
對於100%資料,1<=n<=1000000,1<=a[i]<=10^8.
tips:我沒有想故意卡你們時限。一點這樣的意思都沒有。你們不要聽風就是雨……
比賽已結束 詳細解析見題解
分類標籤 Tags 點此展開
連樹狀陣列求逆序對我都不會寫了,,好弱啊
關於怎麼實現,推薦一篇部落格
http://www.cnblogs.com/xiongmao-cpp/p/5043340.html
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #define LL long long 7 #define lb(x) ((x)&(-x)) 8 using namespace std; 9 const int MAXN=40000001; 10 inline int read() 11 { 12 char c=getchar();int x=0,f=1; 13 while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();} 14 while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();return x*f; 15 } 16 int n; 17 int tree[MAXN]; 18 int a[MAXN]; 19 int data[MAXN]; 20 inline void Point_Add(int pos,int val) 21 { 22 while(pos<=n) 23 { 24 tree[pos]+=val; 25 pos+=lb(pos); 26 } 27 } 28 inline int Interval_Sum(int pos) 29 { 30 int ans=0; 31 while(pos) 32 { 33 ans+=tree[pos]; 34 pos-=lb(pos); 35 } 36 return ans; 37 } 38 int main() 39 { 40 n=read();LL ans=0; 41 for(int i=1;i<=n;i++) a[i]=read(),data[i]=a[i]; 42 int num=unique(data,data+n+1)-data-1; 43 sort(data+1,data+n+1); 44 for(int i=1;i<=n;i++) a[i]=lower_bound(data+1,data+num+1,a[i])-data; 45 for(int i=1;i<=n;i++) 46 { 47 Point_Add(a[i],1); 48 ans+=i-Interval_Sum(a[i]); 49 } 50 printf("%lld",ans); 51 return 0; 52 }