// Krzysztof Baranski (2021.12.06)
#include <algorithm>
#include <cstdio>
#include <bitset>
using namespace std;
int n, k, min_n;
bitset<500002> types_of_wine;
int shelf[500002];
int help_shelf[500002];
long long merge(int begin, int end, int part) {
register int a = begin, i = begin, j = part+1;
register long long inversions = 0;
while(i <= part && j <= end) {
if(shelf[i] <= shelf[j]) {
help_shelf[a++] = shelf[i++];
} else {
help_shelf[a++] = shelf[j++];
inversions += (part - i + 1);
}
}
while(i <= part) help_shelf[a++] = shelf[i++];
while(j <= end) help_shelf[a++] = shelf[j++];
// rewrite from helper shelf to main shelf
for(i = begin; i <= end; ++i) shelf[i] = help_shelf[i];
return inversions;
}
long long mergesort(int begin, int end) {
if(begin >= end) return 0;
// split point
register int part = begin + ((end - begin) >> 1);
register long long inversions = 0;
// sort partitions
inversions += mergesort(begin, part);
inversions += mergesort(part + 1, end);
inversions += merge(begin, end, part);
return inversions;
}
//===========================================================================| MAIN
int main() {
scanf("%d %d", &n, &k);
// loading heights
register int type_of_wine;
register int number_of_types = 0;
for(register int i = 0; i < n; ++i) {
scanf("%d", &type_of_wine);
if(number_of_types >= k) {
continue;
}
// if new type of wine, place it on the left, otherwise on the right
if(!types_of_wine.test(type_of_wine)) {
shelf[i] = 0;
types_of_wine.set(type_of_wine);
++number_of_types;
} else {
shelf[i] = 1;
}
++min_n;
};
if(number_of_types < k) {
printf("-1\n");
return 0;
}
// count inversions
register long long inversions = mergesort(0, min_n - 1);
printf("%lld\n", inversions);
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | // Krzysztof Baranski (2021.12.06) #include <algorithm> #include <cstdio> #include <bitset> using namespace std; int n, k, min_n; bitset<500002> types_of_wine; int shelf[500002]; int help_shelf[500002]; long long merge(int begin, int end, int part) { register int a = begin, i = begin, j = part+1; register long long inversions = 0; while(i <= part && j <= end) { if(shelf[i] <= shelf[j]) { help_shelf[a++] = shelf[i++]; } else { help_shelf[a++] = shelf[j++]; inversions += (part - i + 1); } } while(i <= part) help_shelf[a++] = shelf[i++]; while(j <= end) help_shelf[a++] = shelf[j++]; // rewrite from helper shelf to main shelf for(i = begin; i <= end; ++i) shelf[i] = help_shelf[i]; return inversions; } long long mergesort(int begin, int end) { if(begin >= end) return 0; // split point register int part = begin + ((end - begin) >> 1); register long long inversions = 0; // sort partitions inversions += mergesort(begin, part); inversions += mergesort(part + 1, end); inversions += merge(begin, end, part); return inversions; } //===========================================================================| MAIN int main() { scanf("%d %d", &n, &k); // loading heights register int type_of_wine; register int number_of_types = 0; for(register int i = 0; i < n; ++i) { scanf("%d", &type_of_wine); if(number_of_types >= k) { continue; } // if new type of wine, place it on the left, otherwise on the right if(!types_of_wine.test(type_of_wine)) { shelf[i] = 0; types_of_wine.set(type_of_wine); ++number_of_types; } else { shelf[i] = 1; } ++min_n; }; if(number_of_types < k) { printf("-1\n"); return 0; } // count inversions register long long inversions = mergesort(0, min_n - 1); printf("%lld\n", inversions); } |
English