码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5497 Inversion

时间:2016-07-06 23:17:09      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:

 

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 }

 

HDU 5497 Inversion

标签:

原文地址:http://www.cnblogs.com/SilverNebula/p/5648291.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!