\(\mathcal{Description}\)

  给定排列 \(\{a_n\}\),求字典序第 \(K\) 大的合法排列 \(\{b_n\}\)。称一个排列 \(\{p_n\}\) 合法,当且仅当依次将 \([1,m],[2,m+1],\cdots,[n-m+1,n]\) 内的 \(p\) 升序排列后,得到的排列为 \(\{a_n\}\) 相同。

  \(n\le2 \times 10^6\),\(m\le 100\),\(K\le2 \times 10^{16}\) 。

\(\mathcal{Solution}\)

  应该说是构造题吧,想到几乎所有结论却打不出分 qwq。

  显然,\(b_i\) 在 \(\{a_n\}\) 中的下标属于集合 \([\max\{1,i-m+1\},n]\),反过来,\(a_i\) 在 \(\{b_n\}\) 中对应的下标属于集合 \([1,\min\{i+m-1,n\}]\)。

  然后可以发现 \(\{a_n\}\) 中的逆序对非常特殊。有性质:

\[ (\exists j\in[1,i))(a_i<a_j) \Rightarrow b_{i+m-1}=a_i
\]

  归纳证明。考虑一对 \((i,j)\),满足 \(\max_{k\in(i,j)}\{a_k\}<a_j<a_i\),若 \(i+1=j\),显然;否则对于 \(k\in(i,j)\),已有 \(b_{k+m-1}=a_k\),不妨设 \(b_x=a_j\),则 \(x\not\in[i+m,j+m-2]\),而 \(x\in[1,\min\{j+m-1,n\}]\),又有 \(x\ge i+m\),所以 \(x=j+m-1\) 成立。

  所以可以直接确定所有存在逆序对的 \(j\) 的位置。接下来考虑 \(\{a_n\}\) 是一个单增排列的情况。

  从左往右构造 \(\{b_n\}\),我们需要求出固定 \(\{b_n\}\) 的前缀时所有合法 \(\{b_n\}\) 的方案数。不妨设固定前 \(i\) 位,对于一个没有出现的 \(a_j\),其放置方案数显然为 \(\min\{j+m-1,n\}-i\)。乘法原理就可以得到所求,最后类似多叉树求第 \(K\) 大地枚举就好,复杂度 \(\mathcal O(n^3)\)。

  由于方案数是指数增长,所以前面很多位直接从小到达钦定,再对后缀的 \(\mathcal O(\log_mn)\) 暴力构造即可。

  复杂度 \(\mathcal O(n+\log^3n)\)。

\(\mathcal{Code}\)

/* Clearink */

#include <cstdio>
#include <algorithm> typedef long long LL; inline LL rint () {
LL x = 0; char s = getchar ();
for ( ; s < '0' || '9' < s; s = getchar () );
for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
return x;
} template<typename Tp>
inline void wint ( Tp x ) {
if ( x < 0 ) putchar ( '-' ), x = ~ x + 1;
if ( 9 < x ) wint ( x / 10 );
putchar ( x % 10 ^ '0' );
} inline int min_ ( const int a, const int b ) { return a < b ? a : b; } const int MAXN = 2e6;
int n, m, a[MAXN + 5];
LL K;
int top, stk[MAXN + 5], ans[MAXN + 5];
bool used[MAXN + 5]; inline void setnxt ( int& pos, const int x ) { for ( ; ans[pos]; ++ pos ); ans[pos] = x; } int main () {
freopen ( "gift.in", "r", stdin );
freopen ( "gift.out", "w", stdout );
n = rint (), m = rint (), K = rint ();
for ( int i = 1; i <= n; ++ i ) a[i] = rint ();
for ( int i = 1; i <= n; ++ i ) {
if ( a[i] < a[stk[top]] ) ans[i + m - 1] = a[i];
else stk[++ top] = i;
}
int mut = top, pos = 1;
for ( LL all = 1; mut && all < K; -- mut ) {
all *= min_ ( m, top - mut + 2 );
}
for ( int i = 1; i < mut; ++ i ) setnxt ( pos, a[stk[i]] );
for ( int i = mut; i <= top; ++ i ) {
for ( int j = mut; j <= top; ++ j ) {
if ( used[j] ) continue;
used[j] = true;
LL all = 1;
for ( int k = mut, pre = i; k <= top; ++ k ) {
if ( !used[k] ) {
all *= min_ ( top, k + m - 1 ) - pre ++;
}
}
if ( all < K ) K -= all, used[j] = false;
else { setnxt ( pos, a[stk[j]] ); break; }
}
}
for ( int i = 1; i <= n; ++ i ) {
wint ( ans[i] );
putchar ( i ^ n ? ' ' : '\n' );
}
return 0;
}

Solution -「LOCAL」「cov. 牛客多校 2020 第三场 I」礼物的更多相关文章

  1. Solution -「LOCAL」「cov. 牛客多校 2020 第五场 C」Easy

    \(\mathcal{Description}\)   Link.(完全一致)   给定 \(n,m,k\),对于两个长度为 \(k\) 的满足 \(\left(\sum_{i=0}^ka_i=n\r ...

  2. 2019牛客多校训练第三场H.Magic Line(思维)

    题目传送门 大致题意: 输入测试用例个数T,输入点的个数n(n为偶数),再分别输入n个不同的点的坐标,要求输出四个整数x1,y1,x2,y2,表示有一条经过点(x1,y1),(x2,y2)的直线将该二 ...

  3. 2019牛客多校训练第三场B.Crazy Binary String(思维+前缀和)

    题目传送门 大致题意: 输入整数n(1<=n<=100000),再输入由n个0或1组成的字符串,求该字符串中满足1和0个数相等的最长子串.子序列. sample input: 801001 ...

  4. 牛客多校对抗第6场 A Singing Contest

    [20分]标题:A.Singing Contest | 时间限制:1秒 | 内存限制:256MJigglypuff is holding a singing contest. There are 2n ...

  5. 牛客多校训练第八场C.CDMA(思维+构造)

    题目传送门 题意: 输入整数m( m∈2k ∣ k=1,2,⋯,10),构造一个由1和-1组成的m×m矩阵,要求对于任意两个不同的行的内积为0. 题解: Code: #include<bits/ ...

  6. 牛客多校训练第八场G.Gemstones(栈模拟)

    题目传送门 题意: 输入一段字符串,字符串中连续的三个相同的字符可以消去,消去后剩下的左右两段字符串拼接,求最多可消去次数. 输入:ATCCCTTG   输出:2 ATCCCTTG(消去CCC)——& ...

  7. 2019牛客多校训练第四场K.number(思维)

    题目传送门 题意: 输入一个只包含数字的字符串,求出是300的倍数的子串的个数(不同位置的0.00.000等都算,并考虑前导零的情况). sample input: 600 1230003210132 ...

  8. 2019暑假牛客多校训练-第八场-C-CDMA(递归、水题)

    观察前3组可以推出递归规律,生成下一个类型时,每行copy自身与自身相反. 题目描述 Gromah and LZR have entered the third level. There is a b ...

  9. 2018年牛客多校寒假 第四场 F (call to your teacher) (图的连通性)

    题目链接 传送门:https://ac.nowcoder.com/acm/contest/76/F 思路: 题目的意思就是判断图的连通性可以用可达性矩阵来求,至于图的存储可以用邻接矩阵来储存,求出来可 ...

随机推荐

  1. 使用Kubernetes两年来的7大经验教训

    来源:分布式实验室译者:冯旭松在Ridecell公司管理基础设施团队几年后,我想在停下来休息时记录一些想法和经验教训. 1Kubernetes不仅仅是炒作 我在Kubernetes领域里活跃了很久,所 ...

  2. Enumy:一款功能强大的Linux后渗透提权枚举工具

    Enumy是一款功能强大的Linux后渗透提权枚举工具,该工具是一个速度非常快的可移植可执行文件,广大研究人员可以在针对Linux设备的渗透测试以及CTF的后渗透阶段利用该工具实现权限提升,而Enum ...

  3. 【Java常用类】两个Date类

    两个Date类 java.util.Date类 两个构造器的使用 构造器一:Date():创建一个对应当前时间的Date对象 构造器二:创建指定毫秒数的Date对象 两个方法的使用 toString( ...

  4. 流言粉碎机:JAVA使用 try catch 会严重影响性能

    目录 一.JVM 异常处理逻辑 二.关于JVM的编译优化 1. 分层编译 2. 即时编译器 1. 解释模式 2. 编译模式 3. 提前编译器:jaotc 三.关于测试的约束 执行用时统计 编译器优化的 ...

  5. vscode自定义代码片段,自定义注释片段(动态时间)

    下载vscode 一.打开vscode,点击左下角设置图标. 二.点击用户代码片段 三.点击新建全局代码片段文件 四.输入自定义代码片段配置文件名,例如:vue.json 五.进行代码片段配置示例如下 ...

  6. 不难懂------react-flux

    一.什么是Flux Flux 是一种架构思想,专门解决软件的结构问题.它跟MVC 架构是同一类东西,但是更加简单和清晰. 二.flux的基本概念 (1) .Flux由4部分组成 1.View:视图层 ...

  7. [数据结构]伸展树(Splay)

    #0.0 写在前面 Splay(伸展树)是较为重要的一种平衡树,理解起来也依旧很容易,但是细节是真的多QnQ,学一次忘一次,还是得用博客加深一下理解( #1.0 Splay! #1.1 基本构架 Sp ...

  8. DB2重组表失败处理办法

    set integrity for XXX all immediate unchecked reorg table XXX allow no access 如set integrity for a a ...

  9. JVM之栈、堆、方法区(三)

    一.CPU和内存的交互 今天除夕,祝大家新年快乐,其实,我们知道的,我们的CPU跟内存会有非常频繁的交互,因为如果这个频繁的交互是交给我们的磁盘的话,那么随着我们的CPU运转速度越来越快,那么我们的磁 ...

  10. __rept__和__str__

    最近一下子学了很多的知识点,导致我有点没反应过来,粗略的在草稿纸记了点自己的想法,趁休息的时间将它敲到博客里面去,免得丢失,这一篇写的挺废话的,有点啰嗦,本篇的重点是第二段程序后开始的总结和后面的几个 ...