Codeforces 526D Om Nom and Necklace kmp+hash

题目链接:点击打开链接

题意:

给出长度为n的字符串,常数k

下面一个长度为n的字符串。

问:

for(int i = 1; i <= n; i++){

字符串的前i个字符 能否构成 形如A+B+A+B+A+B+A的形式,其中A有k+1个,B有k个 A和B是2个任意的字符串(也可以为空串)

若可以构成则输出1,否则输出0

}

思路:

POJ1961

先用kmp求一个前缀循环节,。

我们观察 ABABABA => AB, AB, AB, A 所以前缀循环节有K个,而后面的A是尽可能地和AB长度接近,所以hash+二分求A的最长长度。

思路2:

直接枚举AB串的长度,然后二分A串的长度即可。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <vector>
template <class T>
inline bool rd(T &ret) {
	char c; int sgn;
	if (c = getchar(), c == EOF) return 0;
	while (c != '-' && (c<'0' || c>'9')) c = getchar();
	sgn = (c == '-') ? -1 : 1;
	ret = (c == '-') ? 0 : (c - '0');
	while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
	ret *= sgn;
	return 1;
}
template <class T>
inline void pt(T x) {
	if (x <0) {
		putchar('-');
		x = -x;
	}
	if (x>9) pt(x / 10);
	putchar(x % 10 + '0');
}
using namespace std;
const int N = 1000005;
typedef long long ll;
typedef unsigned long long ull;

const int maxn = 2000 * 1000 + 100, base1 = 131, base2 = 127;
const int mod = 1000000007;

int hash1[maxn], hash2[maxn], p1[maxn], p2[maxn];
inline int get(int l, int r){
	l--;
	int ret = hash1[r] - 1LL * hash1[l] * p1[r - l ] % mod;
	if (ret<0)
		ret += mod;
	return ret;
}
int n, k, dp[N];
char s[N];

void work(){
	memset(dp, 0, sizeof dp);
	for (int y = n / k; y; y--){
		int len = y*k;
		if (dp[len] != 0)continue;
		ull now = get(1, y);
		bool ok = true;
		for (int j = 2; j <= k && ok; j++)
		{
			if (get(j*y - y + 1, j*y) != now)
				ok = false;
		}
		if (ok)dp[len]++;
		else {
			continue;
		}
		int las = len;

		int l = len + 1, r = min(len + y, n);
		while (l <= r){
			int mid = (l + r) >> 1;
			if (get(1, mid - len) == get(len + 1, mid)){
				las = max(las, mid);
				l = mid + 1;
			}
			else r = mid - 1;
		}
		dp[las + 1] --;
	}
}
int hehe;
int haha;
int main(){
	p1[0] = 1;
	for (int i = 1; i<maxn; i++)
		p1[i] = 1LL * p1[i - 1] * base1%mod;
	scanf("%d%d", &n, &k);
	scanf("%s", s + 1);
	for (int i = 1; i <= n; i++)
		hash1[i] = (1LL * hash1[i - 1] * base1 + s[i]) % mod;
	if (k > n){ while (n-- > 0)putchar('0'); puts(""); return 0; }
	work();
	int now = 0;
	for (int i = 1; i <= n; i++){
		now += dp[i];
		putchar('0' + (now>0));
	}
	puts("");
	return 0;
}
时间: 2024-12-15 17:53:00

Codeforces 526D Om Nom and Necklace kmp+hash的相关文章

Codeforces 526D - Om Nom and Necklace 【KMP】

ZeptoLab Code Rush 2015 D. Om Nom and Necklace [题意] 给出一个字符串s,判断其各个前缀是否是 ABABA…ABA的形式(A和B都可以为空,且A有Q+1个,B有Q个,Q给定). [官方题解] 对于前缀P,我们可以把它拆成P=SSSS…SSSST,其中T是S的前缀.显然可以用KMP算法,时间复杂度是O(n). 当T=S:P=SSS…S.假设S出现了R次.如果转换为ABABAB…ABABA的形式,A和B是由几个S组成,而且最后的A一定是P的一个后缀.由

Codeforces 526D Om Nom and Necklace (KMP)

http://codeforces.com/problemset/problem/526/D 题意 给定一个串 T,对它的每一个前缀能否写成 A+B+A+B+...+B+A+B+A+B+...+B+A 的形式(k +1个 A,k 个 B,均可为空串) 分析 官方题解 对于前缀P,我们可以把它拆成P=SSSS…SSSST,其中T是S的前缀.显然可以用KMP算法,时间复杂度是O(n). 当T=S:P=SSS…S.假设S出现了R次.如果转换为ABABAB…ABABA的形式,A和B是由几个S组成,而且最

codeforces 526 d Om Nom and Necklace next数组的灵活运用

codeforces 526 d Om Nom and Necklace 题意: 给出一个字符串,问对于字符串的每个位置p,求从0到p的字符串是否符合格式:S=A+B+A+B+A+...+A+B+A,其中A,B是字符串,且可以是空串. 限制: 字符串长度1e6 思路: next数组的灵活运用. /*codeforces 526 d Om Nom and Necklace 题意: 给出一个字符串,问对于字符串的每个位置p,求从0到p的字符串是否符合格式:S=A+B+A+B+A+...+A+B+A,

Codeforces C - Om Nom and Candies

C - Om Nom and Candies 思路:贪心+思维(或者叫数学).假设最大值max(wr,wb)为wr,当c/wr小于√c时,可以枚举r糖的数量(从0到c/wr),更新答案,复杂度√c:否则,假设hr/wr<hb/wr,得到hr*wb<hb*wr,由这个等式可知,在有wb*wr重量限制的情况下,买wb个r糖没有买wr个b糖划算,当需要买超过wb个r糖时,不如去买b糖,可以枚举r糖的数量(从0到wb-1),更新答案,复杂度√c. 代码: #include<bits/stdc++

Codeforces 526C - Om Nom and Candies

A sweet little monster Om Nom loves candies very much. One day he found himself in a rather tricky situation that required him to think a bit in order to enjoy candies the most. Would you succeed with the same task if you were on his place? One day,

Codeforces 526B Om Nom and Dark Park 树形dp

题意:给你一颗完全二叉树,每条边有一个值,可以对这个值进行加操作,让你满足根节点到所有叶子节点路径值相同  ,问你最少要加多少值. 解题思路:从上往下树形DP,位运算会比较方便. 解题代码: 1 // File Name: b.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月05日 星期日 00时47分32秒 4 5 #include<vector> 6 #include<list> 7 #include<map&g

Codeforces 525C Om Nom and Candies 枚举 + 复杂度分析

题意:给你无穷多的A,B物品,现在你有承重C的背包,给你A,B物品的价值和重量,问你如何取使得价值最大. 解题思路:很巧秒的枚举. 解题代码: 1 // File Name: c.cpp 2 // Author: darkdream 3 // Created Time: 2015年04月05日 星期日 01时16分14秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set>

Codeforces 526C - Om Nom and Candies(贪心,暴力)

题意:你最多可以吃C千克的糖,   有两种糖,每种糖有两个参数,一个为重 w  ,一个为欢乐度 h , 如何选择才能拥有最高的欢乐度,  两种糖数量不限. 题解:看了半天题解才理解如何做, 分为两种枚举政策涵盖了所有情况, 时间复杂度为sqrt(c),神奇的暴力 1.如果两种糖中重量最大的超过sqrt(c),  那么该糖最多也只能选择不超过sqrt(c)个,   直接枚举该糖个数,记录最大欢乐度 2.如果两种糖重量都小于sqrt(c),那么从性价比来考虑 我们可以买到Wb个a糖果的同时也可以将其

ZeptoLab Code Rush 2015 B. Om Nom and Dark Park DFS

B. Om Nom and Dark Park Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/526/problem/B Description Om Nom is the main character of a game "Cut the Rope". He is a bright little monster who likes visiting friends living a