http://acm.hdu.edu.cn/showproblem.php?pid=6628
数据范围T = 40 N = 20 K <= 1e4看起来好像很大的样子
但如果仔细分析复杂度的话暴力搜索 1e4个叶子节点的复杂度最多也不会超过1e5(带常数)
因此这个题可以构造一种搜索序列硬生生遍历1w个子结果即可
一种比较简单的实现方式,对于8以下的序列,直接库函数生成所有结果排列并排序(8!)
8以上的构造前length - 8位对最后八位进行排列并排序
因为8!是4e4 > K 1e4, 7!是5040太小不合适
所有8!的排列是包含所有情况的,得解。
同时观察到T是40 N是20 离线一下可以优化至少一半
代码:
/*
Zeolim - An AC a day keeps the bug away
*/
//pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define mp(x, y) make_pair(x, y)
#define fr(x, z, y) for(int x = z; x < y; ++x)
typedef long long ll;
typedef double ld;
typedef std::pair<int, int> pii;
typedef std::vector <short> vi;
//typedef __int128 ill;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const ll INF = 1e18;
const ll MOD = 998244353;
const int MAXN = 1e6 + 100;
int n, m;
int brr[50];
struct node
{
int v[50];
} arr[MAXN];
bool cmp(node a, node b)
{
for(int i = 1; i < n; ++i)
{
int p = a.v[i] - a.v[i - 1], q = b.v[i] - b.v[i - 1];
if(p != q)
return p < q;
}
}
struct q
{
int n, k, id;
int ans[25];
} qst[50];
bool cmp1(q a, q b)
{
return a.n < b.n;
}
bool cmp2(q a, q b)
{
return a.id < b.id;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
//freopen("d:out.txt","w",stdout);
//freopen("d:in.txt","r",stdin);
int T;
cin >> T;
for(int i = 1; i <= T; ++i)
{
qst[i].id = i;
cin >> qst[i].n >> qst[i].k;
}
sort(qst + 1, qst + 1 + T, cmp1);
for(int k = 1; k <= T; ++k)
{
n = qst[k].n, m = qst[k].k;
if(qst[k].n != qst[k - 1].n)
{
int cnt = 0;
if(n <= 8)
{
for(int i = 0; i < n; ++i)
{
brr[i] = i + 1;
}
do
{
++cnt;
for(int i = 0; i < n; ++i)
{
arr[cnt].v[i] = brr[i];
}
}
while(next_permutation(brr, brr + n) );
}
else
{
brr[0] = n;
for(int i = 1; i < n; ++i)
brr[i] = i;
do
{
++cnt;
for(int i = 0; i < n; ++i)
{
arr[cnt].v[i] = brr[i];
}
}
while(next_permutation(brr + n - 8, brr + n) );
}
sort(arr + 1, arr + cnt + 1, cmp);
for(int i = 0; i < n; ++i)
{
qst[k].ans[i] = arr[m].v[i];
}
}
else
{
for(int i = 0; i < n; ++i)
{
qst[k].ans[i] = arr[m].v[i];
}
}
}
sort(qst + 1, qst + 1 + T, cmp2);
for(int i = 1; i <= T; ++i)
{
for(int j = 0; j < qst[i].n; ++j)
{
if(j)
cout << ' ';
cout << qst[i].ans[j];
}
cout << '
';
}
return 0;
}