[题解](排列/逆序对)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]);
}
原文地址:https://www.cnblogs.com/superminivan/p/10883450.html