/* Solution to the problems solved during the last exercise: * 1. PermSwap * 2. Events * 3. Schedule * 4. Pancakes */ #include #include #include #include #include #include #include #include #include using namespace std; using lli = long long int; // PERMSWAP BEGIN /* Template Merge Sort * The following merge sort will be used for three of the solved problems * For the next two we won't need the inversion counting but who cares * who cares == (generally a bad practice but in competitive programming it is fine) */ template lli cntInvMerge(vector &v, int left, int right, vector &temp) { int middle = left + (right - left) / 2; int i = left, j = middle + 1, k = left; lli cnt = 0; while (i <= middle && j <= right) { temp[k++] = v[j] < v[i] ? (cnt += middle - i + 1, v[j++]) : v[i++]; } while (i <= middle) { temp[k++] = v[i++]; } while (j <= right) { temp[k++] = v[j++]; } std::copy(temp.begin() + left, temp.begin() + k, v.begin() + left); return cnt; } template lli cntInvMergeSort(vector &v, int left, int right, vector &temp) { if (left >= right) { return 0; } int middle = left + (right - left) / 2; lli invcnt = cntInvMergeSort(v, left, middle, temp); invcnt += cntInvMergeSort(v, middle + 1, right, temp); invcnt += cntInvMerge(v, left, right, temp); return invcnt; } void permswap() { int N; scanf("%d", &N); vector v(N), temp(N); for (int i = 0; i < N; i++) { scanf("%d", &v[i]); } printf("%lld\n", cntInvMergeSort(v, 0, N - 1, temp)); } // PERMSWAP END // EVENTS (SUBITIYA) BEGIN struct Event { int idx, y, d, s; bool operator<(const Event &other) const { if (y != other.y) { return y < other.y; } if (d != other.d) { return d < other.d; } return s < other.s; } }; void events() { int N; scanf("%d", &N); vector v(N), temp(N); int month, day, hour, minute, second; for (int i = 0; i < N; i++) { scanf("%d:%d:%d %d.%d.%d", &hour, &minute, &second, &day, &month, &v[i].y); v[i].s = hour * 3600 + minute * 60 + second; v[i].d = month * 31 + day; v[i].idx = i + 1; } cntInvMergeSort(v, 0, N - 1, temp); for (int i = 0; i < N; i++) { printf("%d\n", v[i].idx); } } // EVENTS (SUBITIYA) END // SCHEDULE (GRAFIK) BEGIN struct Range { int start, end; bool operator<(const Range &rhs) const { return end != rhs.end ? end < rhs.end : start < rhs.start; } }; int getMaxEvents(vector &events) { int count = 0; if (!events.empty()) { count++; Range last = events[0]; for (int i = 1; i < events.size(); i++) { if (last.end <= events[i].start) { last = events[i]; count++; } } } return count; } void schedule() { vector events, temp; Range current; int duration; while (scanf("%d %d", ¤t.start, &duration) == 2) { current.end = current.start + duration; events.push_back(current); } temp.resize(events.size()); cntInvMergeSort(events, 0, events.size() - 1, temp); printf("%d\n", getMaxEvents(events)); } // SCHEDULE (GRAFIK) END // PANCAKES (PALACHINKI) BEGIN int partition(vector &v, int start, int end) { // In the real solution replace 0xDABEDA with some random generated number // (It works with 0xDABEDA too though) int pivotIndex = start + 0xDABEDA % (end - start + 1); swap(v[start], v[pivotIndex]); int index = start + 1, temp; for (int i = start + 1; i <= end; i++) { if (v[i] < v[start]) { swap(v[index], v[i]); index++; } } --index; swap(v[start], v[index]); return index; } int quickSelect(vector &v, int N, int K) { // here we can shuffle the elements // std::random_shuffle(v.begin(), v.end()); <- deprecated int start = 0, end = N - 1, pivotIndex; while (start <= end) { pivotIndex = partition(v, start, end); if (pivotIndex < K - 1) { start = pivotIndex + 1; } else if (pivotIndex > K - 1) { end = pivotIndex - 1; } else { return v[K - 1]; } } return v[K - 1]; } void pancakes() { int T, N, K; vector v; v.resize(100000); scanf("%d", &T); int pivotIndex, left, right; for (int i = 0; i < T; i++) { scanf("%d %d", &N, &K); for (int j = 0; j < N; j++) { scanf("%d", &v[j]); } printf("%d\n", quickSelect(v, N, K)); } } // PANCAKES (PALACHINKI) END int main() { //permswap(); //events(); //schedule(); //pancakes(); return 0; }