刷题之路-数论
洛谷P1338末日的传说
做题思路
这题的意思有点难懂,在查看了题解后才明白。题目的大概意思就是:求出一个长度为排列,其中有m个逆序对,且字典序最小。
不知道怎么证明,但答案的形式一定是上升序列+一个数字+一个下降序列。
代码
#include<iostream>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<functional>
#include<cmath>
#include<cstdlib>
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
typedef pair<int, int> pii;
typedef long long ll;
const int N = 50005;
const int M = 1000005;
int ans[N];
int main()
{
int n, m;
cin >> n >> m;
if (m == 0)
{
for (int i = 1; i <= n; i++) cout << i << ' ';
return 0;
}
int j;
ll sum, sum1 = (ll)n * (n - 1) / 2;
for (j = 1;; j++)
{
sum = (ll)(n - j) * (ll)(n - j - 1) / 2;
if (m > sum) break;
sum1 = sum;
}
for (int i = 1; i < j; i++) cout << i << ' ';
ll x = n - (sum1 - m);
cout << x << ' ';
for (int i = n; i >= j; i--)
{
if (i != x) cout << i << ' ';
}
return 0;
}