題解:AT_arc181_b [ARC181B] Annoying String Problem

辜铜星發表於2024-08-17

思路

首先我們可以根據兩個字串算出另外一個字串 \(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
題解AtcoderARC

相關文章