• [题解](排列/逆序对)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]);
    }
  • 相关阅读:
    推荐几个不错的console调试技巧
    JS字符串截取函数slice(),substring(),substr()的区别
    ES6入门基础
    setTimeout的小尴尬
    Javascript自定义事件功能与用法实例分析
    JavaScript中函数定义的三种方法
    数组方法
    数组选择排序
    数组冒泡排序
    this指向问题(1)
  • 原文地址:https://www.cnblogs.com/superminivan/p/10883450.html
Copyright © 2020-2023  润新知