首页 > 代码库 > 2014多校第五场1001 || HDU 4911 Inversion (归并求逆序数)
2014多校第五场1001 || HDU 4911 Inversion (归并求逆序数)
题目链接
题意 : 给你一个数列,可以随意交换两相邻元素,交换次数不超过k次,让你找出i < j 且ai > aj的(i,j)的对数最小是多少对。
思路 : 一开始想的很多,各种都想了,后来终于想出来这根本就是求逆序数嘛,可以用归并排序,也可以用树状数组,不过我们用树状数组做错了,也不知道为什么。求出逆序数来再减掉k次,就可以求出最终结果来了。求逆序数链接1,链接2
1 #include <stdio.h> 2 3 int left[250003], right[250003]; 4 long long count; 5 6 void merge(int* a, int p, int q, int r) 7 { 8 int i, j, k, n1, n2; 9 10 n1 = q-p+1;11 n2 = r-q;12 for (i=0; i<n1; i++)13 {14 left[i] = a[p+i];15 }16 for (i=0; i<n2; i++)17 {18 right[i] = a[q+i+1];19 }20 left[n1] = right[n2] = 0x7fffffff;21 22 i = j = 0;23 for (k=p; k<=r; k++)24 {25 if (left[i] <= right[j])26 {27 a[k] = left[i];28 i++;29 }30 else31 {32 a[k] = right[j];33 j++;34 count += n1-i;35 }36 }37 return;38 }39 40 void mergesort(int* a, int p, int r)41 {42 int q;43 if (p < r)44 {45 q = (p+r)/2;46 mergesort(a, p, q);47 mergesort(a, q+1, r);48 merge(a, p, q, r);49 }50 return ;51 }52 53 int main()54 {55 int n, i, a[500001];56 long long k;57 58 while (scanf("%d%I64d", &n,&k)!=EOF)59 {60 count = 0;61 for (i=0; i<n; i++)62 {63 scanf("%d", &a[i]);64 }65 mergesort(a, 0, n-1);66 count -=k;67 if(count<0)count=0;68 printf("%I64d\n",count );69 }70 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。