codeforces 1087 E. Vasya and Templates(字符串哈希)

题目链接: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;





}

猜你喜欢

转载自blog.csdn.net/weixin_42640692/article/details/86516608