1. 程式人生 > >【洛谷習題】末日的傳說

【洛谷習題】末日的傳說

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) / 2
) 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 }
AC代碼

【洛谷習題】末日的傳說