2014 Yandex.Algorithm Elimination Stage, Round 2 D - Inversions
解法
長さを最小化するので,N * (N - 1) / 2 >= K && (N - 1) * (N - 2) / 2 < K となる最小の N を求める.
あとは,上から順に,その位置の値を変えなければならないところまで順番に 1 から埋めていく.
その場所まで来たら,変えないと行けない数字と swap して,残りの後ろの数を降順に並べるだけ.
コード読んだほうが早い.いつものやつだし.
計算量は O(NlogN)
ソースコード
#include <bits/stdc++.h> using namespace std; int main() { int K; cin >> K; int sz = 1; while(sz * (sz - 1) / 2 < K) ++sz; vector<int> ans(sz); iota(begin(ans), end(ans), 1); for(int i = 0; i < sz; ++i) { const int sz2 = sz - i; const int offset = K - (sz2 - 1) * (sz2 - 2) / 2; if(offset > 0) { swap(ans[i], ans[i + offset]); sort(begin(ans) + i + 1, end(ans)); reverse(begin(ans) + i + 1, end(ans)); break; } } cout << sz << endl; for(int i = 0; i < sz; ++i) { cout << ans[i] << " \n"[i + 1 == sz]; } }