1. 程式人生 > >洛谷P1908 逆序對(歸並排序)

洛谷P1908 逆序對(歸並排序)

pac 序列 sort tdi ios cst main pre pri

題目描述

貓貓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。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 using namespace std;
 5 const int MAXN=100001;
 6 inline int read()
 7 {
 8     char c=getchar();int x=0,flag=1;
 9     while(c<0||c>9)    {if
(c==-) flag=-1;c=getchar();} 10 while(c>=0&&c<=9) x=x*10+c-48,c=getchar();return x*flag; 11 } 12 int n; 13 int a[MAXN]; 14 int tmp[MAXN]; 15 int ans=0; 16 void Sort(int l,int r) 17 { 18 if(l==r) return ; 19 int mid=l+r>>1; 20 Sort(l,mid);Sort(mid+1
,r); 21 int nowl=l,nowr=mid+1,nowpos=l; 22 while(nowl<=mid&&nowr<=r) 23 { 24 if(a[nowl]<=a[nowr]) tmp[nowpos++]=a[nowl],nowl++; 25 else tmp[nowpos++]=a[nowr],nowr++,ans=ans+mid-nowl+1; 26 } 27 while(nowl<=mid) tmp[nowpos++]=a[nowl],nowl++; 28 while(nowr<=r) tmp[nowpos++]=a[nowr],nowr++; 29 for(int i=l;i<=r;i++) a[i]=tmp[i]; 30 } 31 int main() 32 { 33 n=read(); 34 for(int i=1;i<=n;i++) a[i]=read(); 35 Sort(1,n); 36 printf("%d",ans); 37 return 0; 38 }

洛谷P1908 逆序對(歸並排序)