HDU 4944 逆序数对

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4911

题意:

给出一个序列,可以相邻的交换k次,求 k 次之后,逆序数对最少是多少;

分析:

可以发现,无论怎么交换之后,总共的逆序数对只会-1,那么结果就是,将这个序列排整齐时,要两两交换的次数-k;题目就转换为求这个序列的逆序数对有多少;

这样的两两交换好像是冒泡排序,冒泡排序是O(n^2);

正确解法是归并排序;当我们合并两个有序序列时,如果,要将后面的插入到前一个中间,那么这里就有m-i+1个逆序数对;

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 const int maxn = 1e5 + 5;
 6
 7 __int64 cnt,k;
 8 int a[maxn],c[maxn];
 9
10
11 void merge(int* a,int first,int mid,int last,int* c) {
12     int i = first,j=mid+1;
13     int m = mid,n=last;
14     int k = 0;
15     while(i<=m||j<=n) {
16         if(j>n||(i<=m&&a[i]<=a[j])) {
17             c[k++] = a[i++];
18         }
19         else {
20             c[k++] = a[j++];
21             cnt += (m-i+1);
22         }
23     }
24     for(i=0;i<k;i++)
25         a[first+i] = c[i];
26 }
27
28 void mergeSort(int* a,int first,int last,int* c) {
29     if(first<last) {
30         int mid = (first+last)/2;
31         mergeSort(a,first,mid,c);
32         mergeSort(a,mid+1,last,c);
33         merge(a,first,mid,last,c);
34     }
35 }
36
37 int main()
38 {
39     int n;
40     while(~scanf("%d%I64d",&n,&k)) {
41         for(int i=0;i<n;i++)
42             scanf("%d",&a[i]);
43         memset(c,0,sizeof(c));
44         cnt = 0;
45         mergeSort(a,0,n-1,c);
46         printf("%lld\n",max(cnt-k,0LL));
47     }
48     return 0;
49 }

时间: 2024-10-18 13:40:04

HDU 4944 逆序数对的相关文章

HDU 1394 (逆序数) Minimum Inversion Number

原来求逆序数还可以用线段树,涨姿势了. 首先求出原始序列的逆序数,然后递推每一个序列的逆序数. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int maxn = 20000 + 10; 7 8 int n, p, qL, qR; 9 int sum[maxn], a[5000 + 10]; 10 11 void updat

hdu 1394 Minimum Inversion Number 逆序数/树状数组

Minimum Inversion Number Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1394 Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai

HDU 1394 Minimum Inversion Number 【逆序数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题目大意:给一个n,然后给出一组0~n-1的序列,求这个序列的逆序数,以及交换之后的逆序数中的最小值.交换规则是: a1, a2, ..., an-1, an (where m = 0 - the initial seqence) a2, a3, ..., an, a1 (where m = 1) a3, a4, ..., an, a1, a2 (where m = 2) ... an, a1

HDU 4911 Inversion 求逆序数对

点击打开链接 Inversion Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1106    Accepted Submission(s): 474 Problem Description bobo has a sequence a1,a2,-,an. He is allowed to swap two adjacent num

HDU 1394 Minimum Inversion Number (树状数组求逆序数)

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 13942    Accepted Submission(s): 8514 Problem Description The inversion number of a given number sequence a1, a2, ..., a

HDU 1394 Minimum Inversion Number (线段树 单点更新 求逆序数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给你一个n个数的序列,其中组成的数只有0-n,我们可以进行这么一种操作:把第一个数移到最后一个,次数不限.问,在原始数列和最新生成的数列中逆序数最小可以是多少? 刚开始以为需要枚举求逆序数,但最后知道了这个题是有规律的:一个由0-n组成的n个数的数列,当第一个数移到最后一位的时候,整个数列的逆序数会减少x[i](移动前,后面比他小的),会增加n-x[i]-1(移动后,前面比他大的). 那

hdu 1394 Minimum Inversion Number (裸树状数组 求逆序数)

题目链接 题意: 给一个n个数的序列a1, a2, ..., an ,这些数的范围是0-n-1, 可以把前面m个数移动到后面去,形成新序列:a1, a2, ..., an-1, an (where m = 0 - the initial seqence)a2, a3, ..., an, a1 (where m = 1)a3, a4, ..., an, a1, a2 (where m = 2)...an, a1, a2, ..., an-1 (where m = n-1)求这些序列中,逆序数最少的

HDU 1394 Minimum Inversion Number(线段树求逆序数)

题目地址:HDU 1394 这题可以用线段树来求逆序数. 这题的维护信息为每个数是否已经出现.每次输入后,都从该点的值到n-1进行查询,每次发现出现了一个数,由于是从该数的后面开始找的,这个数肯定是比该数大的.那就是一对逆序数,然后逆序数+1.最后求完所有的逆序数之后,剩下的就可以递推出来了.因为假如目前的第一个数是x,那当把他放到最后面的时候,少的逆序数是本来后面比他小的数的个数.多的逆序数就是放到后面后前面比他大的数的个数.因为所有数都是从0到n-1.所以比他小的数就是x,比他大的数就是n-

HDU 1394- Minimum Inversion Number(线段树求逆序数)

Minimum Inversion Number Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1394 Appoint description:  System Crawler  (2015-04-13) Description The inversion number of a given number sequence a1, a