codevs 4163 hzwer與逆序對

自為風月馬前卒發表於2017-10-22
 時間限制: 1 s
 空間限制: 256000 KB
 題目等級 : 黃金 Gold
 
 
 
題目描述 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 }

 

相關文章