HDU 5497 Inversion

Time Limit: 3000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u

Description

You have a sequence \{a_1,a_2,...,a_n\} and you can delete a contiguous subsequence of length m. So what is the minimum number of inversions after the deletion.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains two integers n, m (1 \le n \le 10^5, 1 \le m < n) - the length of the seuqence. The second line contains n integersa_1,a_2,...,a_n (1 \le a_i \le n).

The sum of n in the test cases will not exceed 2 \times 10^6.

Output

For each test case, output the minimum number of inversions.

Sample Input

2
3 1
1 2 3
4 2
4 1 3 2

Sample Output

0
1

Source

BestCoder Round #58 (div.2)

滑动区间扫描。用树状数组来维护逆序对的个数(数组存储数n是否已经出现,通过计算数组前缀和来求逆序对,思路和比这篇早些写的POJ2182 Lost Cows类似)

维护L([i])树状数组表示i左边比a[i]的数的数量,R([i])树状数组表示i右边比a[i]小的数的数量。窗口从左滑到右面,不断更新L和R,计算答案并更新

 1 /*by SilverN*/
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8 const int mxn=110000;
 9 int n,m;
10 struct tree{
11     int a[mxn];
12     inline lowbit(int x){return x&-x;}
13     void init(){memset(a,0,sizeof a);}
14     void add(int x,int num){
15         while(x<=n){
16             a[x]+=num;
17             x+=lowbit(x);
18         }
19         return;
20     }
21     int sum(int x){
22         int res=0;
23         while(x){
24             res+=a[x];
25             x-=lowbit(x);
26         }
27         return res;
28     }
29 };
30 int a[mxn];
31 tree Le,Ri;
32 int main(){
33     int T;
34     scanf("%d",&T);
35     while(T--){
36         scanf("%d%d",&n,&m);
37         int i,j;
38         for(i=1;i<=n;i++){
39             scanf("%d",&a[i]);
40         }
41         Le.init();
42         Ri.init();
43         long long ans;
44         long long tmp=0;
45         //求原有逆序对数(最左边滑动窗口内的不算)
46         for(i=n;i>m;i--){
47             Ri.add(a[i],1);
48             tmp+=Ri.sum(a[i]-1);
49         }
50         ans=tmp;
51         //finish
52         for(i=1;i<=n-m;i++){
53             Ri.add(a[i+m],-1);//窗口滑动,窗口最右面的数被删除
54             tmp=tmp+Ri.sum(a[i]-1)-Ri.sum(a[i+m]-1);
55             tmp=tmp+Le.sum(n+1-(a[i]+1))-Le.sum(n+1-(a[i+m]+1));
56             Le.add(n+1-a[i],1);
57             ans=min(ans,tmp);
58         }
59         printf("%lld\n",ans);
60     }
61     return 0;
62 }
时间: 2024-10-27 02:41:45

HDU 5497 Inversion的相关文章

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 4911 Inversion

Inversion Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 197    Accepted Submission(s): 82 Problem Description bobo has a sequence a1,a2,-,an. He is allowed to swap two adjacent numbers for

HDU 4911 Inversion(归并求逆序对)

HDU 4911 Inversion 题目链接 题意:给定一个数组,可以相邻交换最多k次,问交换后,逆序对为多少 思路:先利用归并排序求出逆序对,然后再减去k就是答案 代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N = 100005; int n, num[N], save[N], sn; void init() { for

hdu 4911 Inversion(归并)

题目链接:hdu 4911 Inversion 题目大意:给定一个序列,有k次机会交换相邻两个位置的数,问说最后序列的逆序对数最少为多少. 解题思路:每交换一次一定可以减少一个逆序对,所以问题转换成如何求逆序对数. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 1e5+5; ll k

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];

hdu 4911 Inversion(归并排序求逆序对数)

Inversion                                                                             Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description bobo has a sequence a1,a2,-,an. He is allowed to swap two 

hdu 4911 Inversion(求逆序数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4911 Inversion Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 528    Accepted Submission(s): 228 Problem Description bobo has a sequence a1,a2,

HDU 4911 Inversion(归并排序求逆序数)

归并排序求逆序数,然后ans-k与0取一个最大值就可以了. 也可以用树状数组做,比赛的时候可能姿势不对,树状数组wa了.. Inversion Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 578    Accepted Submission(s): 249 Problem Description bobo has a seque

HDU 4911 Inversion(基本算法-排序)

Inversion Problem Description bobo has a sequence a1,a2,-,an. He is allowed to swap two adjacent numbers for no more than k times. Find the minimum number of inversions after his swaps. Note: The number of inversions is the number of pair (i,j) where