zoukankan      html  css  js  c++  java
  • 【洛谷习题】末日的传说

    题目链接: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代码
  • 相关阅读:
    单页应用 SPA(Sigle Page Aolication)
    初学数据库
    AJAX与跨域
    面向对象
    event、Dom
    HTML DOM Event 对象
    JavaScript RegExp 对象
    UNITY常用插件
    数据分析师
    VBA工作表排序转载
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9795004.html
Copyright © 2011-2022 走看看