码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces —— Check Transcription(1056E)

时间:2020-10-26 11:20:37      阅读:23      评论:0      收藏:0      [点我收藏+]

标签:main   ||   memset   int   lowbit   turn   namespace   匹配   def   

技术图片

input

01
aaaaaa

output

4

input

001
kokokokotlin

output

2

技术图片

题意:

给定一个划分0代表一个子串,1代表一个子串,问用01子串的方式来表示原串的01组合有多少种,并且01子串不能相同

思路

可以枚举首部的子串长度,然后用该长度可以计算出相对应的子串长度,对它们进行哈希,遇到不满足条件的情况下就
跳出否则就继续依照给定的01串来进行匹配直到结束;> 
时间复杂度给定的s的长度的约数个数,乘以01串的长度,1e6范围内约数个数最多为240,所以时间复杂度就位O(1e7)

代码

#pragma GCC optimize(2)
#include<iostream>
#include<unordered_map>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<map>
#include<set>
#define Buff ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define rush() int Case = 0; int T; cin >> T;  while(T--)
#define rep(i, a, b) for(int i = a; i <= b; i ++)
#define per(i, a, b) for(int i = a; i >= b; i --)
#define reps(i, a, b) for(int i = a; b; i ++)
#define clc(a, b) memset(a, b, sizeof(a))
#define Buff ios::sync_with_stdio(false)
#define readl(a) scanf("%lld", &a)
#define readd(a) scanf("%lf", &a)
#define readc(a) scanf("%c", &a)
#define reads(a) scanf("%s", a)
#define read(a) scanf("%d", &a)
#define lowbit(n) (n&(-n))
#define pb push_back
#define sqr(x) x*x
#define lson rt<<1
#define rson rt<<1|1
#define ls lson, l, mid
#define rs rson, mid+1, r
#define y second
#define x first
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int>PII;
const int mod = 1e9+7;
const double eps = 1e-6;
const int N = 1e6+7;
ll h1[N], p1[N];
ll h2[N], p2[N];
char s[N], t[N];
int s0, s1, n, m;
void init()
{
	p1[0] = p2[0] = 1;
	reps(i, 1, t[i])
	{
		h1[i] = (h1[i-1] * 131 + t[i]) % mod;
		h2[i] = (h2[i-1] * 13331 + t[i]) % mod;
		p1[i] = (p1[i-1] * 131) % mod;
		p2[i] = (p2[i-1] * 13331) % mod;
	}
}
ll query(int l, int r, ll* h, ll* p)
{
	return (((h[r] - h[l-1] * p[r-l+1]) % mod + mod) % mod);
}
int main()
{
	cin >> s+1 >> t+1;
	n = strlen(s+1);
	m = strlen(t+1);
	rep(i, 1, n) 
	{
		s0 += (s[i] == ‘0‘);
		s1 += (s[i] == ‘1‘);
	}	
	init();
	ll res = 0;
	for(int x = 1, y; x < m; x ++)
	{
		if(x * s0 >= m)	break;
		if((m - x * s0) % s1) continue;
		y = (m - x * s0) / s1;
		bool flag = true;
		ll has1_r0 = 0, has1_r1 = 0;
		ll has2_r0 = 0, has2_r1 = 0;
		int t0 = 0, t1 = 0;
		for(int i = 1; i <= n; i ++)
		{
			if(s[i] == ‘0‘)
			{
				int l = t0 * x + t1 * y + 1;
				int r = l + x - 1;
				ll has1 = query(l, r, h1, p1);
				ll has2 = query(l, r, h2, p2);
				if(!has1_r0 && !has2_r0)	has1_r0 = has1, has2_r0 = has2;
				else if(has1_r0 != has1 || has2_r0 != has2)
				{
					flag = false;
					break;
				}
				t0 ++;
			}
			else
			{
				int l = t0 * x + t1 * y + 1;
				int r = l + y - 1;
				ll has1 = query(l, r, h1, p1);
				ll has2 = query(l, r, h2, p2);
				if(!has1_r1 && !has2_r1)	has1_r1 = has1, has2_r1 = has2;
				else if(has1_r1 != has1 || has2_r1 != has2)
				{
					flag = false;
					break;
				}
				t1 ++;
			}
			// cout << i <<endl;
			// cout << "has1_r0, has1_r1" <<" "<< has1_r0 <<" "<< has1_r1 <<endl;
			// cout << "has2_r0, has2_r1" <<" "<< has2_r0 <<" "<< has2_r1 <<endl;
			if((has1_r0 && has1_r1 && has1_r1 == has1_r0) ||
			   (has2_r0 && has2_r1 && has2_r1 == has2_r0))
			{
				flag = false;
				break;
			}
		}
		if(flag)	
		{
			res ++;
			// cout << "x, y:" << x <<" "<< y <<endl;
			// cout << "has_r0, has_r1: " << has_r0 <<" "<< has_r1 <<endl;
		}
	}
	cout << res <<endl;
	return 0;
}

Codeforces —— Check Transcription(1056E)

标签:main   ||   memset   int   lowbit   turn   namespace   匹配   def   

原文地址:https://www.cnblogs.com/Farrell-12138/p/13873897.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!