关闭

【bzoj3796】Mushroom追妹纸 hash+二分答案

487人阅读 评论(0) 收藏 举报
分类:

嗯,好久没写hash了。

先处理出s3在s1和s2的位置,然后二分答案,看有没有s1和s2有没有公共子串不包含就可以了。


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#define maxn 50010
#define mod 10007

using namespace std;

vector<int> v[mod];
char s1[maxn],s2[maxn],s[maxn];
int hash11[maxn],hash21[maxn];
int p1[maxn];
unsigned long long p2[maxn],hash12[maxn],hash22[maxn];
int n,m;
unsigned long long Hash;
bool vis1[maxn],vis2[maxn];
int next1[maxn],next2[maxn];
int hash,len1,len2,len;

int calc11(int l,int r)
{
	l++;r++;
	return (hash11[r]-hash11[l-1]*p1[r-l+1]%mod+mod)%mod; 
}

int calc21(int l,int r)
{
	l++;r++;
	return (hash21[r]-hash21[l-1]*p1[r-l+1]%mod+mod)%mod;
}

unsigned long long calc12(int l,int r)
{
	l++;r++;
	return hash12[r]-hash12[l-1]*p2[r-l+1];
}

unsigned long long calc22(int l,int r)
{
	l++;r++;
	return hash22[r]-hash22[l-1]*p2[r-l+1];
}

bool query(int l,int r)
{
	int x=calc21(l,r),y=calc22(l,r);
	for (int i=0;i<v[x].size();i++)
	  if (v[x][i]==y) return 1;
	return 0;
}

bool check(int x)
{
	if (x==0) return 0;
	for (int i=0;i<mod;i++) v[i].clear();
	for (int i=0;i+x-1<len1;i++)
	  if (next1[i]==len1 || i+x-1<next1[i]+len-1)
	    v[calc11(i,i+x-1)].push_back(calc12(i,i+x-1));
	for (int i=0;i+x-1<len2;i++)
	  if (next2[i]==len2 || i+x-1<next2[i]+len-1)
	    if (query(i,i+x-1)) return 1;
	return 0;
}

int main()
{
	scanf("%s%s%s",s1,s2,s);
	len=strlen(s);len1=strlen(s1);len2=strlen(s2);
	for (int i=1;i<=len1;i++) hash11[i]=(hash11[i-1]*233+s1[i-1]-'a')%mod;
	for (int i=1;i<=len1;i++) hash12[i]=hash12[i-1]*2333+s1[i-1]-'a';
	for (int i=1;i<=len2;i++) hash21[i]=(hash21[i-1]*233+s2[i-1]-'a')%mod;
	for (int i=1;i<=len2;i++) hash22[i]=hash22[i-1]*2333+s2[i-1]-'a';
	for (int i=1;i<=len;i++) hash=(hash*233+s[i-1]-'a')%mod,Hash=Hash*2333+s[i-1]-'a';

	p1[0]=1;p2[0]=1;
	for (int i=1;i<=max(len,max(len1,len2));i++) p1[i]=p1[i-1]*233%mod,p2[i]=p2[i-1]*2333;
	for (int i=0;i+len-1<len1;i++) if (calc11(i,i+len-1)==hash && calc12(i,i+len-1)==Hash) vis1[i]=1;
	for (int i=0;i+len-1<len2;i++) if (calc21(i,i+len-1)==hash && calc22(i,i+len-1)==Hash) vis2[i]=1;
	next1[len1]=len1;for (int i=len1-1;i>=0;i--) if (vis1[i]) next1[i]=i; else next1[i]=next1[i+1];
	next2[len2]=len2;for (int i=len2-1;i>=0;i--) if (vis2[i]) next2[i]=i; else next2[i]=next2[i+1];
	
	int l=0,r=min(len1,len2),ans;
	while (l<=r)
	{
		int mid=(l+r)/2;
		if (check(mid)) ans=mid,l=mid+1;
		else r=mid-1;
	}
	printf("%d\n",ans);
	return 0;
}


0
0
查看评论

bzoj-3796 Mushroom追妹纸

题意: 给出三个字符串s1,s2,s3; 求一个最长的串满足: 1.它是s1的子串; 2.它是s2的子串; 3.s3不是它的子串; s1,s2长度 题解: 这道题的前两个条件算是比较裸吧; 求后缀数组,二分答案,在height数组上验证; 如果不会的去看看我之前的题解...
  • ww140142
  • ww140142
  • 2015-09-03 14:15
  • 714

bzoj 3796: Mushroom追妹纸 (后缀数组+KMP+二分)

题目描述传送门题目大意: 求一个字符串满足 1、w是s1的子串 2、w是s2的子串 3、s3不是w的子串 4、w的长度应尽可能大题解刚开始想用SAM做,想了半天发现不是很可做啊。 还是好好想后缀数组的做法吧。这道题最恶心的限制就是限制3:s3不是w的子串。 那么如果没有这个限制该怎么做...
  • clover_hxy
  • clover_hxy
  • 2017-03-28 16:25
  • 244

BZOJ 3796 Mushroom追妹纸 后缀数组+KMP

BZOJ 3796 Mushroom追妹纸 后缀数组+KMP
  • wzq_QwQ
  • wzq_QwQ
  • 2015-09-04 22:42
  • 1597

[BZOJ3796]Mushroom追妹纸(hash+后缀数组+二分)

题目描述传送门题解把s1和s2接在一起,中间加一个分隔符 预处理出s3在s1和s2中的哪些位置出现过(hash) 求出sa和height,容易知道答案一定在相邻的两个在不同串里的后缀中产生 对于每一对相邻的后缀,二分一下满足条件的最大长度,即没有出现s3(前缀和) 时间复杂度O(nlogn)...
  • Clove_unique
  • Clove_unique
  • 2017-03-28 16:18
  • 404

bzoj3796 Mushroom追妹纸(SA+二分答案+kmp)

把s1和s2接在一起,求最长公共子串。二分答案就好了。。。此题就多一个判断,要求s3不能出现在公共子串里,那我们就预处理一下,用kmp求出s3在s2中出现的位置,处理成L数组,即可O(1)判断。
  • Icefox_zhx
  • Icefox_zhx
  • 2017-08-26 16:58
  • 217

BZOJ 3796: Mushroom追妹纸 哈希+二分

DescriptionMushroom最近看上了一个漂亮妹纸。他选择一种非常经典的手段来表达自己的心意——写情书。考虑到自己的表达能力,Mushroom决定不手写情书。他从网上找到了两篇极佳的情书,打算选择其中共同的部分。另外,Mushroom还有个一个情敌Ertanis,此人也写了封情书给妹子。 ...
  • LZJ209
  • LZJ209
  • 2017-06-14 21:58
  • 202

bzoj 3796 Mushroom追妹纸 后缀数组 kmp

一开始写了个后缀自动机,还调了半天,然后发现gg了。。。 果然后缀自动机不支持删除所有包含一个子串的节点(好像什么都不支持。。。。)先把s1,s2连到一起,中间用非法字符隔开。 先kmp求有哪些位置有s3,然后可以求每个点开始往后不包含s3的最长前缀。 求一个后缀数组。从前往后扫一遍后缀数组...
  • make_it_for_good
  • make_it_for_good
  • 2016-10-28 18:13
  • 74

一个妹子图应用客户端android源码

源码GankMeizhi,也是一个干·妹纸应用的客户端,目前该应用还没有上传到应用商店中,大家可以自行修改一下吧,没错。又是一个妹子图app,依然采集自干货集中营。 源码下载: http://code.662p.com/view/11060.html  ...
  • lituanjieba
  • lituanjieba
  • 2015-08-19 09:19
  • 820

多少妹纸在平安夜被骗出去说吃苹果

多少妹纸在平安夜被骗出去说吃苹果,结果成了吃香蕉,吃完香蕉还要喝豆浆。为什么呢?哦,因为苹果英文翻译汉语就是"挨炮"。
  • KnowKjava
  • KnowKjava
  • 2014-12-24 13:42
  • 771

跟叶子学把妹——教程序猿把妹第五集…

该系列是公司内部美女叶子同事的文章,偶觉得写的很好,征得同意后分享给单身的程序员。PS:继续跟吧,叶子说最后会爆照。 前四期的“无节操”已经让小叶子变得毫无底限了,我决定暂收我的屌丝心理,拿我的亲身经历,帮你们好好解析一下泡妞的精髓所在之“约会”(正面临情感困惑的小叶子突然想温情一下下) ...
  • ZHANGHUI3239619
  • ZHANGHUI3239619
  • 2017-12-07 22:47
  • 73
    个人资料
    • 访问:193098次
    • 积分:4923
    • 等级:
    • 排名:第6855名
    • 原创:305篇
    • 转载:0篇
    • 译文:0篇
    • 评论:72条
    最新评论