Codeforces 513B2 - Permutations (思维)

来源:互联网 发布:mysql定时执行sql语句 编辑:程序博客网 时间:2024/04/30 03:17

题意

P为一个序列。

定义F(p)=ni=1nj=imin(pi,pi+1,...,pj)

现在要求输出所有满足F(n)最大的序列中字典序第k大的序列。

思路

先求出怎样的序列能满足F(p)最大。

假设现在是一个空的序列,那么1是最小的元素,它只能被放在序列的最前面或者最后面。因为如果放在中间产生的结果必定小。

之后考虑2,也和1一样。把1填的那个位置去除之后2也只能放在剩下来的最前面或者最后面。以此类推。

所以总共合法的排列有2n1个。

接下来考虑字典序。

当放1时,如果放第一个,那么剩下来的可能数是2n11,当k大于这个数时,显然1放前面无法到达第k大字典序。所以这时候要放后面。

剩下来的排列数其实就是2nnum1

以此类推。把1放后面之后减去1放前面能得到的情况,然后考虑2。和考虑1是一样的。

代码

int vis[100];vector<int> ans;int main(){    LL n, k;    cin >> n >> k;    int pos = 1;    for (int i = 0; i < n; i++)        for (; pos <= n; pos++)        {            if (k > (1ll<<(n-pos-1))) k -= (1ll<<(n-pos-1));            else            {                vis[pos] = 1;                ans.PB(pos);                pos++;                break;            }        }    for (int i = n; i >= 1; i--)    {        if (vis[i]) continue;        ans.PB(i);    }    for (auto i: ans) printf("%d ", i);    return 0;}
0 0