Inversion
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1398 Accepted Submission(s): 570
Problem Description
bobo has a sequence a
1,a
2,…,a
n. 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 a i>a j.
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 a i>a j.
Input
The input consists of several tests. For each tests:
The first line contains 2 integers n,k (1≤n≤10 5,0≤k≤10 9). The second line contains n integers a 1,a 2,…,a n (0≤a i≤10 9).
The first line contains 2 integers n,k (1≤n≤10 5,0≤k≤10 9). The second line contains n integers a 1,a 2,…,a n (0≤a i≤10 9).
Output
For each tests:
A single integer denotes the minimum number of inversions.
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
若存在逆序数不为0,则当前这次交换一定能使的逆序数变小。
所以,只要统计初始逆序数大小是否大于k,若大于k,则减去k,否则为0.
统计逆序数用线段树。
#include <iostream>
#include <cstdio>
#include <map>
#include <vector>
using namespace std;
const int maxn = 100020;
struct tree{
int l , r , sum;
}a[4*maxn];
map<int , int> mp;
vector<int> num;
int n , K , cnt;
void build(int l , int r ,int k){
a[k].l = l;
a[k].r = r;
a[k].sum = 0;
if(l != r){
int mid = (l+r)/2;
build(l , mid , 2*k);
build(mid+1 , r , 2*k+1);
}
}
void add(int l , int r , int k ,int c){
//cout << "a[k].l=" << a[k].l << " a[k].r=" << a[k].r << " l="<<l << " r=" << r << endl;
if(l <= a[k].l && a[k].r <= r){
a[k].sum += c;
}else{
int mid = (a[k].l+a[k].r)/2;
if(mid >= r) add(l , r , 2*k , c);
else if(mid < l) add(l , r , 2*k+1 , c);
else add(l ,mid , 2*k , c) , add(mid+1 , r , 2*k+1 , c);
a[k].sum = a[2*k].sum+a[2*k+1].sum;
}
}
int querry(int l , int r , int k){
//cout << "a[k].l=" << a[k].l << " a[k].r=" << a[k].r << " l="<<l << " r=" << r << endl;
if(l <= a[k].l && a[k].r <= r){
return a[k].sum;
}else{
int mid = (a[k].l+a[k].r)/2;
if(mid >= r) return querry(l , r , 2*k);
else if(l > mid) return querry(l , r , 2*k+1);
else return querry(l , mid , 2*k)+querry(mid+1 , r , 2*k+1);
}
}
void initial(){
mp.clear();
num.clear();
cnt = 1;
}
void readcase(){
int tem;
for(int i = 0; i < n; i++){
scanf("%d" , &tem);
num.push_back(tem);
mp[tem] = 0;
}
for(map<int , int>::iterator it = mp.begin(); it != mp.end(); it++){
it->second = cnt++;
}
}
void computing(){
build(0 , cnt , 1);
long long int ans = 0;
for(int i = 0; i < num.size(); i++){
ans += querry(mp[num[i]]+1 , cnt , 1);
add(mp[num[i]] , mp[num[i]] , 1 , 1);
}
//cout << "ans=" << ans << endl;
if(ans < K) printf("0\n");
else printf("%I64d\n" , ans-K);
}
int main(){
while(~scanf("%d%d" ,&n , &K)){
initial();
readcase();
computing();
}
return 0;
}