构造一个字符集大小没有限制的字符串,使得不同的子串个数恰好为K。
K<=1e9,要求串长不超过1e5
假设数列是a个1+b个2+c个1,a>=c
不同的子序列总数 ab+bc+ac+a+b=k
(a+c+1)(b+c+1)=k+(c+1)(c+1)
枚举 c+1 即可
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int K;
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
while (~scanf("%d",&K)){
if (K<=1e5){
printf("%d\n",K);
for (int i=1;i<=K;i++)
printf("1 ");
printf("\n");
continue;
}
int k,a,b,c,flag=0,t;
for (int i=1;i<=33333 && !flag;i++){
k=K+i*i,t=sqrt(k);
for (int j=1;j<=t && !flag;j++)
if (k%j==0){
c=i-1,a=k/j-i,b=j-i;
if (a>=c && a+b+c<=1e5) flag=1;
}
}
printf("%d\n",a+b+c);
while (a--) printf("1 ");
while (b--) printf("2 ");
while (c--) printf("1 ");
printf("\n");
}
return 0;
}
dls有很玄妙的做法