Description
给定 (k),要找到一个最小的正整数 (n) 使得存在 (1 sim n) 的一个全排列,它不是任何一个字符集大小不超过 (k) 的字符串的后缀排名数组。输出 (n) 以及一个合法的全排列。
Solution
神仙构造。整体思路是让奇偶位的顺序颠倒。
举个例子,(k=5) 时,我们取 (n=6),则
sa[] = {5, 3, 1, 2, 4, 6}
rk[] = {3, 4, 2, 5, 1, 6}
考虑所有后缀的首位,显然至少有两个是相等的,并且它们一定可以是在后缀排序中相邻的。
假如 (a[5]=a[3]),则根据 (s[5:]<s[3:]),一定有 (s[4:]<s[6:]),但由已知 (s[6:]<s[4:]),矛盾。
以此类推,即可证明正确性,即总是存在一个 (1 o k+1) 的全排列,使得它不是任意一个字符集大小不超过 (k) 的字符串的后缀排名数组。
考虑最小性,对于 (n=k),显然我们可以随意构造,同理可知 (n le k) 均不可。
综上,(n=k+1),构造方式即类似 rk[] = {3, 4, 2, 5, 1, 6}
这样的操作。
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n,k,a[N];
signed main()
{
cin>>k;
n=k+1;
cout<<n<<endl;
int i=n,x=1,y=n;
while(i>0)
{
a[i--]=y--;
a[i--]=x++;
}
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
}