hdu 4911 Inversion

Inversion

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 68    Accepted Submission(s): 23


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 1≤i<j≤n and ai>aj.
 
Input
The input consists of several tests. For each tests:

The first line contains 2 integers n,k (1≤n≤105,0≤k≤109). The second line contains n integers a1,a2,…,an (0≤ai≤109).
 
Output
For each tests:

A single integer denotes the minimum number of inversions.
 
Sample Input
3 1
2 2 1
3 0
2 2 1
 
Sample Output
1
2
树状数组求逆序对,如果总对数大于k 就减k,否则置为0
 1 #include<iostream>
 2 #include<string>
 3 #include<cstdio>
 4 #include<vector>
 5 #include<queue>
 6 #include<stack>
 7 #include<algorithm>
 8 #include<cstring>
 9 #include<stdlib.h>
10 #include<string>
11 #include<cmath>
12 #include<map>
13 using namespace std;
14 #define pb push_back
15 #define mmax 100000
16 #define ll __int64
17 #define mod 1000000007
18 ll p[101000];
19 int ac[101000],tmp[101000],cnt;
20 int n,m;
21 int Find(int x){
22     int l=1,r=cnt,mid,tt=10000000;
23     while(l<=r){
24         mid=(l+r)>>1;
25         if(tmp[mid]>=x) tt=min(tt,mid),r=mid-1;
26         else l=mid+1;
27     }
28     return tt;
29 }
30 void update(int pos,int num){
31     while(pos>0){
32         p[pos]+=num;
33         pos-=pos&(-pos);
34     }
35 }
36 ll getnum(int pos){
37     ll sum=0;
38     while(pos<=cnt){
39         sum+=p[pos];
40         pos+=pos&(-pos);
41     }
42     return sum;
43 }
44 int main(){
45     while(cin>>n>>m){
46         for(int i=1;i<=n;i++){
47              scanf("%d",&ac[i]);
48              tmp[i]=ac[i];
49         }
50         memset(p,0,sizeof(p));
51         sort(tmp+1,tmp+1+n);离散化
52         cnt=0;
53         tmp[++cnt]=tmp[1];
54         ll sum=0;
55         for(int i=2;i<=n;i++) if(tmp[i]!=tmp[cnt]) tmp[++cnt]=tmp[i];
56         for(int i=1;i<=n;i++){
57             int x=Find(ac[i]);
58             sum+=getnum(x+1);
59             update(x,1);
60         }
61         if(sum>=m) sum-=m;
62         else sum=0;
63         printf("%I64d
",sum);
64     }
65 }
原文地址:https://www.cnblogs.com/ainixu1314/p/3892902.html