hdu 4911Inversion

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

题意:给定一个序列和k,求在k次交换之后序列的逆序数,只能相邻两个数交换且只有左边的数大于右边时才能交换

代码如下

 1 #include<cstdio>  
 2 #include<iostream>  
 3 #include<algorithm>
 4 #include<math.h> 
 5 #include<string.h>  
 6 #include<vector> 
 7 #include<queue>
 8 #include<iterator>
 9 #include<vector>
10 #include<set>
11 #define dinf 0x3f3f3f3f
12 typedef long long ll;
13 //const int Max=(1<<16)+10;
14 using namespace std;
15 #define SIZE 100000005
16 
17 
18 ll a[10000005],s[10000005],ans,k;
19 
20 ll merge(int l1,int r1,int l2,int r2)
21 {
22     ans=0l;
23     int i,j,k;
24     for(i=l1;i<=r2;i++)
25         s[i]=a[i];
26     
27     i=l1;j=l2;k=l1;
28     while(i<=r1 && j<=r2)
29     {
30         if(s[i]<=s[j])
31             a[k++]=s[i++];
32         else
33         {
34             a[k++]=s[j++];
35             ans+=(r1-i+1);
36         }
37     }
38     while(i<=r1)
39         a[k++]=s[i++];
40     while(j<=r2)
41         a[k++]=s[j++];
42     return ans;
43  } 
44  
45 ll merge_s(int l,int r)
46 {
47     ll ans=0l;
48      if(l<r)
49      {
50          int mid=(l+r)/2;
51          ans+=merge_s(l,mid);
52          ans+=merge_s(mid+1,r);
53          ans+=merge(l,mid,mid+1,r);
54     }
55     return ans;
56  }
57 
58 
59 int main()
60 {
61     int n;
62     while(~scanf("%d %lld",&n,&k))
63     {
64         for(int i=1;i<=n;i++)
65             scanf("%lld",&a[i]);
66         ans=merge_s(1,n);
67         if(k>=ans)
68             printf("0\n");
69         else
70             printf("%lld\n",ans-k);
71     }
72     return 0;
73 }

 

posted @ 2016-07-20 16:05  pter  阅读(125)  评论(0编辑  收藏  举报