【洛谷習題】末日的傳說
阿新 • • 發佈:2018-10-16
alt 題目 否則 can 字典 closed 最小 ext 對數
題目鏈接:https://www.luogu.org/problemnew/show/P1338
不水,不水了。。。
大約一月前學了一下康托展開,初賽就考到了,看看分數,要是沒學初賽就過不去了!!!
所以看到排列,我自然而然想到救過命的康托展開,但是嘗試發現,是行不通的,包括next_permutation和手寫一個生成排列的程序。
沒辦法,看題解吧,居然是O(n)的做法,本來還以為要再帶上點東西的。
我們每次考慮未放過的最小的數,假如他放在從左往右第一個位置,那麽剩下的最大可能產生逆序對數必須小於等於m,否則,他一定不會放在第一個位置,不管他放在哪,因他而產生的逆序對數是確定的,就是他之前空的位置。而這個數放得越靠後,剩下序列的剩下序列的逆序對數也就越少,因此其字典序也就越小,剩下的自然在最後一個位置的前面,這樣最終答案的字典序也就越小,所以我們要放到最後一個位置。
1 #include <cstdio> 2 3 typedef long long ll; 4 5 const int maxn = 5e4 + 5; 6 7 int p[maxn]; 8 9 int main() { 10 int n, m; 11 scanf("%d%d", &n, &m); 12 ll s = 1, t = n; 13 for (int i = 1; i <= n; ++i) { 14 if (m <= (n - i - 1LL) * (n - i) / 2AC代碼) p[s++] = i; 15 else m -= t - s, p[t--] = i; 16 } 17 for (int i = 1; i <= n; ++i) printf("%d ", p[i]); 18 return 0; 19 }
【洛谷習題】末日的傳說