• [题解](排列/逆序对)luogu_P1338末日的传说


    首先我们要考虑怎么排能使逆序对数最多:显然是下降序列时,会产生n*(n-1)/2数量的逆序对

    那么我们肯定是要尽量把序列的尾端安排成下降序列,前面的尽量不动,中间可能有一段排列自适应到m的逆序对数

    然后考虑把每个数加进序列,如果把这个数安排在前面,那么后面最多产生(n-1)*(n-2)/2数量的逆序对数,如果这个数量都不够满足m的话

    就只能把这个数安排在后面了,我们肯定想把这个数安排在序列尾端,这样能产生最多的逆序对贡献

    于是就转化成了一个子问题:n,m分别为:n-1 和 m-(a的贡献),这样递归(其实不用)处理

    我™又爆longlong了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=50009;
    int n,m,a[maxn],head,tail;
    int main(){
        scanf("%d%d",&n,&m);tail=n;
        for(int i=1;i<=n;i++){
            long long t=(long long)(n-i)*(n-i-1)/2;
            if(t>=m)a[++head]=i;
            else a[tail--]=i,m-=(tail-head);
        }
        for(int i=1;i<=n;i++)printf("%d ",a[i]);
    }
  • 相关阅读:
    Jzoj4822 完美标号
    Jzoj4822 完美标号
    Jzoj4792 整除
    Jzoj4792 整除
    Educational Codeforces Round 79 A. New Year Garland
    Good Bye 2019 C. Make Good
    ?Good Bye 2019 B. Interesting Subarray
    Good Bye 2019 A. Card Game
    力扣算法题—088扰乱字符串【二叉树】
    力扣算法题—086分隔链表
  • 原文地址:https://www.cnblogs.com/superminivan/p/10883450.html
Copyright © 2020-2023  润新知