分析
可以发现题目就是求最小的
m
m
m,使
c
o
n
n
(
s
2
,
n
2
∗
m
)
=
c
o
n
n
(
s
1
,
n
1
)
conn(s2,n2*m)=conn(s1,n1)
conn(s2,n2∗m)=conn(s1,n1)
它肯定会有一个上界也就是
n
1
∗
l
e
n
1
/
n
2
n1*len1/n2
n1∗len1/n2,然而这个上界还是很大,考虑用倍增拼凑
设
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示从
s
1
[
j
]
s1[j]
s1[j]开始,能生成
2
i
2^i
2i个
s
2
s2
s2至少需要多少字符
i
=
0
i=0
i=0时就是暴力对吧,之后
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
]
+
d
p
[
i
−
1
]
[
(
j
+
d
p
[
i
−
1
]
[
j
]
−
1
)
 
m
o
d
 
l
e
n
1
+
1
]
dp[i][j]=dp[i-1][j]+dp[i-1][(j+dp[i-1][j]-1)\bmod len1+1]
dp[i][j]=dp[i−1][j]+dp[i−1][(j+dp[i−1][j]−1)modlen1+1],正确性显然、
嗯,然后就是拼凑
代码
#include <cstdio>
#include <cstring>
#include <cmath>
#define rr register
using namespace std;
typedef unsigned uit;
char s1[101],s2[101]; uit k1,k2,dp[31][101];
signed main(){
while (scanf("%s%u%s%u",s2+1,&k2,s1+1,&k1)==4){
rr uit len1=strlen(s1+1),len2=strlen(s2+1),flag=0;
for (rr uit i=1;i<=len1;++i){
rr uit p=0,t1=i,t2=1;
while (p<=len2){
if (s1[t1]==s2[t2]&&++t2>len2) break;
if (++t1>len1) ++p,t1=1;
}
if (p>len2){flag=1; printf("0\n"); break;}
dp[0][i]=p*len1+t1-i+1;
}
if (flag) continue;
rr uit lg=log2(k1*len1/len2)+1;
for (rr uit i=1;i<=lg;++i)
for (rr uit j=1;j<=len1;++j)
dp[i][j]=dp[i-1][j]+dp[i-1][(j+dp[i-1][j]-1)%len1+1];
rr uit t=0,ans=0;
for (rr int i=lg;i>=0;--i)
if (t+dp[i][t%len1+1]<=len1*k1)
t+=dp[i][t%len1+1],ans|=1<<i;
printf("%u\n",ans/k2);
}
return 0;
}