题目链接:http://codeforces.com/contest/1056/problem/E
题意:给你一个只有0,1的字符串s1,和一个含有字母的串s2,问能找出多少种0,1分别对应s2一部分子串的方案,并且0,1对应的字串要不同
思路: 字符串哈希+暴力,先将整个串转化成对应哈希数字,这里不要用ull自动取模 cf上肯定有人会hack (原理见:BZOJ hash killer)
然后暴力枚举0对应的子串长度,因为0,1数字固定,确定了0的长度 就可以确定1的长度,然后就把每一段的0,1对应的s2中的串进行比较,最后has1!=has2 ans++;
这里附加一个学习字符串哈希的链接:
https://www.cnblogs.com/Slager-Z/p/7807011.html
#include<bits/stdc++.h>
#define fi first
#define se second
#define FOR(a) for(int i=0;i<a;i++)
#define sc(a) scanf("%d",&a)
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> LP;
const ll inf = 1e17 + 10;
const int N = 1e6 + 10;
const ll mod = 1000000007;
const int base=131;
map<string, int>ml;
ll b[N], vis[N], po[N],num[N], t, n, m, x, y, k, a[N];
ll ex, ey, cnt, ans, sum, flag;
ll hs[N];
ll dp[N];
vector<int> v[N];
map<int,int> mp;
priority_queue<P> q;
priority_queue<P> tq;
char s1[N];
char s2[N];
ll f(int l,int r)
{
ll sum=(hs[r]-hs[l-1]*po[r-l+1])%mod;
return (sum+mod)%mod;
}
int main()
{
ios::sync_with_stdio ( false );
cin.tie ( 0 );
cin>>s1;
cin>>s2;
ll cnt0=0,cnt1=0;
int l1=strlen(s1);
int l2=strlen(s2);
for(int i=0;s1[i];i++)
{
if(s1[i]=='0') cnt0++;
else cnt1++;
}
po[0]=1;
for(int i=1;i<=l2;i++) po[i]=(po[i-1]*base)%mod;
for(int i=1;i<=l2;i++) hs[i]=(hs[i-1]*base+s2[i-1]-'a'+1)%mod;
for(int i=1;i<=l2;i++)
{
if(cnt0*i>l2) break;
t=l2-cnt0*i;
if(t%cnt1!=0||t<cnt1) continue;
t/=cnt1;
int has1=0,has2=0,l=0,r=0,flag=0;
//show2(i,t);
for(int j=0;j<l1;j++)
{
l=r+1;
if(s1[j]=='0')
{
r+=i;
if(has1==0)
{
has1=f(l,r);
//show2("has1",has1)
}
else if(has1!=f(l,r))
{
flag=1;
break;
}
}
else
{
r+=t;
if(has2==0) has2=f(l,r);
else if(has2!=f(l,r))
{
flag=1;
break;
}
}
//show2("has2",has2)
}
if(has1==has2) flag=1;
if(!flag) ans++;
}
cout<<ans<<endl;
}