思路
首先我们可以根据两个字符串算出另外一个字符串 \(T\) 的长度。
算出来之后,因为我们要满足等式两边完全相等,所以很容易得出这两个字符串应该都是由一些公共的字串拼接而成的。设 \(S\) 串中最小的周期为 \(P\)。所以应该满足 \(| P|\Large{\mid} \normalsize \gcd(|S|,|T|)\)。
其中最小周期可以使用 KMP 算法。如果 \((n-nxt_n)\nmid n\),那么最小周期为 0,否则为 \(n-nxt_n\)。
代码
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
namespace gtx{
// Fast IO
void read(int &x){
x = 0;int h = 1;char tmp;
do{tmp=getchar();if(tmp=='-')h*=-1;}while(!isdigit(tmp));
while(isdigit(tmp)) x*=10,x+=tmp-'0',tmp=getchar();
x*=h;
}
void read(char &x){do{x=getchar();}while(x==' '||x=='\n'||x=='\r');}
void write(char x){putchar(x);}
void write(int x){
if(x<0) putchar('-'),x=-x;int st[200]={0},tot=0;
do{st[++tot]=x%10,x/=10;} while(x);
while(tot){putchar(st[tot--]+'0');};
}
void write(int x,char y){write(x);write(y);}
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 4e6+10;
char a[MAXN];
char x[MAXN],y[MAXN];
int n,nxt[MAXN],p,q,aa,bb,cc,dd;
signed main(){
scanf("%s",a+1);
n = strlen(a+1);
for(int i = 2;i<=n;i++){
int j = nxt[i-1];
while(j&&!(a[j+1]==a[i])) j = nxt[j];
if(a[j+1]==a[i]) j++;
nxt[i] = j;
}
scanf("%s%s",x+1,y+1);
p = strlen(x+1);
q = strlen(y+1);
aa=bb=cc=dd=0;
for(int i = 1;i<=p;i++){
if(x[i]=='0')aa++;
else if(x[i]=='1')bb++;
}
for(int i = 1;i<=q;i++){
if(y[i]=='0')cc++;
else if(y[i]=='1')dd++;
}
aa-=cc;
dd-=bb;
if(dd==0) return puts(aa==0?"Yes":"No");
int size_of_t = n*aa/dd;
if(1ll*n*aa%dd!=0) return puts("No"),0;
if(size_of_t==n) return puts("Yes"),0;
if(size_of_t<0) return puts("No"),0;
int len = (n%(n-nxt[n]))?n:n-nxt[n];
if(__gcd(size_of_t,n)%len==0) return puts("Yes"),0;
return puts("No"),0;
}
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
// ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int T = 1;
gtx::read(T);
while(T--) gtx::main();
return 0;
}
tag
KMP
题解
、Atcoder
、ARC