题目描述
猫猫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 int n; 3 int s[100001],v[100001]; 4 int gb(int x,int y){ 5 if(x==y) return 0; 6 int mid=(x+y)>>1; 7 int ans=gb(x,mid)+gb(mid+1,y); 8 int p=x,j=x,k=mid+1; 9 while(j<=mid&&k<=y){ 10 if(s[j]>s[k]) 11 {ans+=mid-j+1;v[p++]=s[k++];} 12 else v[p++]=s[j++]; 13 } 14 while(j<=mid) v[p++]=s[j++]; 15 while(k<=y) v[p++]=s[k++]; 16 for(int i=x;i<=y;i++) s[i]=v[i]; 17 return ans; 18 } 19 int main(){ 20 scanf("%d",&n); 21 for(int i=1;i<=n;i++) scanf("%d",&s[i]); 22 printf("%d\n",gb(1,n)); 23 return 0; 24 }
题目描述
Description
给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目
数据范围:N<=105。Ai<=105。时间限制为1s。
输入描述
Input Description
第一行为n,表示序列长度,接下来的n行,第i+1行表示序列中的第i个数。
输出描述
Output Description
所有逆序对总数.
样例输入
Sample Input
4
3
2
3
2
样例输出
Sample Output
3
略有改动即可。
代码实现:
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 long long ans,n; 5 int s[100001],v[100001]; 6 void gbpx(int x,int y){ 7 if(x==y) return; 8 int mid=(x+y)/2; 9 gbpx(x,mid);gbpx(mid+1,y); 10 int p=x,j=x,k=mid+1; 11 while(j<=mid&&k<=y){ 12 if(s[j]>s[k]) 13 {ans+=mid-j+1;v[p++]=s[k++];} 14 else v[p++]=s[j++]; 15 } 16 while(j<=mid) v[p++]=s[j++]; 17 while(k<=y) v[p++]=s[k++]; 18 for(int i=x;i<=y;i++) s[i]=v[i]; 19 } 20 int main(){ 21 cin>>n; 22 for(int i=1;i<=n;i++) cin>>s[i]; 23 gbpx(1,n); 24 cout<<ans<<endl; 25 return 0; 26 }
题目来源:洛谷,CODE[VS]