题目链接:https://codeforces.com/contest/1056/problem/E
题目:
One of Arkady's friends works at a huge radio telescope. A few decades ago the telescope has sent a signal s towards a faraway galaxy. Recently they've received a response t which they believe to be a response from aliens! The scientists now want to check if the signal t is similar to s .
The original signal s was a sequence of zeros and ones (everyone knows that binary code is the universe-wide language). The returned signal t , however, does not look as easy as s , but the scientists don't give up! They represented t as a sequence of English letters and say that t is similar to s s if you can replace all zeros in s with some string r0 and all ones in s with some other string r1 and obtain t . The strings r 0 and r1 must be different and non-empty.
Please help Arkady's friend and find the number of possible replacements for zeros and ones (the number of pairs of strings r 0 and r1 ) that transform s to t .
Input
The first line contains a string s ( 2≤|s|≤10^5 ) consisting of zeros and ones — the original signal.
The second line contains a string t (1≤|t|≤10^6 ) consisting of lowercase English letters only — the received signal.
It is guaranteed, that the string s contains at least one '0' and at least one '1'.
Output
Print a single integer — the number of pairs of strings rr0 and r1 that transform s to t .
In case there are no such pairs, print 0 .
Examples
Input
01
aaaaaa
Output
4
Input
001
kokokokotlin
Output
2
Note
In the first example, the possible pairs (r0,r1) are as follows:
- "a", "aaaaa"
- "aa", "aaaa"
- "aaaa", "aa"
- "aaaaa", "a"
The pair "aaa", "aaa" is not allowed, since r0 and r1 must be different.
In the second example, the following pairs are possible:
- "ko", "kokotlin"
- "koko", "tlin"
题解:
题意:第一行给出一个只包含0和1的字符串,第二行给一个只包含小写字母的字符串,问有多少种方案,将第一行的字符串中的0换成字符串r1,1换成字符串r2,拼成的字符串等于第二行的字符串,要求r1和r2非空,而且不相等。
我们可以先算出0的个数和1的个数,假设有a个0,b个1,第二行字符串的长度为n。
然后枚举r1的长度,假设为x,r2的长度为y。
那么x和y要满足 ax+by=n.
枚举出满足ax+by=n的x和y,然后去check这个方案是否合法,合法则答案加1.
枚举可以暴力枚举,也可以用扩展欧几里得算出所有解。
将字符串哈希一下,每次check的时候遍历一遍01字符串。
字符串哈希值取131和13331都在test17 wa了,取13332在test 25 wa了,那么哈希值取13331和13332 双哈希就就过了。
暴力枚举代码
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int maxn=1e6+5;
char c[maxn],s[maxn];
ull p[2]={13331,13332};
ull hs[maxn][2],f[maxn][2];
int n,m;
ull get(int l,int r){
return hs[r][0]-hs[l-1][0]*f[r-l+1][0];
}
ull get2(int l,int r){
return hs[r][1]-hs[l-1][1]*f[r-l+1][1];
}
bool check(int x,int y){
ull r=0,r2=0;
ull rr=0,rr2=0;
int id=1;
for(int i=1;i<=m;i++){
if(c[i]=='0'){
if(r==0) r=get(id,id+x-1),rr=get2(id,id+x-1);
else if(get(id,id+x-1)!=r||get2(id,id+x-1)!=rr) return false;
id+=x;
}else{
if(r2==0) r2=get(id,id+y-1),rr2=get2(id,id+y-1);
else if(get(id,id+y-1)!=r2||get2(id,id+y-1)!=rr2) return false;
id+=y;
}
}
return !(r==r2&&rr==rr2);
}
int main(){
scanf("%s",c+1);
scanf("%s",s+1);
f[0][0]=f[0][1]=1;
n=strlen(s+1);
for(int i=1;i<=n;i++){
hs[i][0]=hs[i-1][0]*p[0]+s[i];
f[i][0]=f[i-1][0]*p[0];
hs[i][1]=hs[i-1][1]*p[1]+s[i];
f[i][1]=f[i-1][1]*p[1];
}
m=strlen(c+1);
int a=0,b=0;
for(int i=1;i<=m;i++){
if(c[i]=='0') a++;
else b++;
}
int ans=0;
for(int x=1;;x++){
if(a*x>=n) break;
if((n-a*x)%b==0){
int y=(n-a*x)/b;
if(check(x,y)) ans++;
}
}
cout<<ans<<endl;
return 0;
}
扩展欧几里得代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn=1e6+5;
char c[maxn],s[maxn];
ull p[2]={13331,13332};
ull hs[maxn][2],f[maxn][2];
int n,m;
int exgcd(int a,int b,int& x,int& y){
if(b==0) { x=1 , y=0; return a; }
int d=exgcd(b,a%b,x,y);
int z=x; x=y; y=z-y*1LL*(a/b);
return d;
}
ull get(int l,int r){
return hs[r][0]-hs[l-1][0]*f[r-l+1][0];
}
ull get2(int l,int r){
return hs[r][1]-hs[l-1][1]*f[r-l+1][1];
}
bool check(int x,int y){
ull r=0,r2=0;
ull rr=0,rr2=0;
int id=1;
for(int i=1;i<=m;i++){
if(c[i]=='0'){
if(r==0) r=get(id,id+x-1),rr=get2(id,id+x-1);
else if(get(id,id+x-1)!=r||get2(id,id+x-1)!=rr) return false;
id+=x;
}else{
if(r2==0) r2=get(id,id+y-1),rr2=get2(id,id+y-1);
else if(get(id,id+y-1)!=r2||get2(id,id+y-1)!=rr2) return false;
id+=y;
}
}
return r!=r2||rr!=rr2;
}
int main(){
scanf("%s",c+1);
scanf("%s",s+1);
f[0][0]=f[0][1]=1;
n=strlen(s+1);
for(int i=1;i<=n;i++){
hs[i][0]=hs[i-1][0]*p[0]+s[i];
f[i][0]=f[i-1][0]*p[0];
hs[i][1]=hs[i-1][1]*p[1]+s[i];
f[i][1]=f[i-1][1]*p[1];
}
m=strlen(c+1);
int a=0,b=0;
for(int i=1;i<=m;i++){
if(c[i]=='0') a++;
else b++;
}
int ans=0;
int d,x,y;
d=exgcd(a,b,x,y);
bool cnt=0;
for(ll k=floor(-1.0*n*x/b)+1;k<ceil(1.0*n*y/a);k++){
cnt++;
int xx=1LL*n/d*x+k*b/d;
int yy=1LL*n/d*y-k*a/d;
if(check(xx,yy)) ans++;
}
cout<<ans<<endl;
return 0;
}