首页 > 代码库 > 【二分答案】【哈希表】【字符串哈希】bzoj2946 [Poi2000]公共串
【二分答案】【哈希表】【字符串哈希】bzoj2946 [Poi2000]公共串
二分答案,然后搞出hash值扔到哈希表里。期望复杂度O(n*log(n))。
#include<cstdio>#include<cstring>#include<vector>using namespace std;typedef unsigned long long ull;const ull seed=29;#define MOD 2007typedef vector<ull>::iterator VER;vector<ull>List[6][2007];ull seeds[2001],ord[301];int n,ls[6],minv=2147483647,mini;char s[6][2001];ull BKDRhash(const char str[],const int &L,const int &R){ ull res=0; for(int i=L;i<R;++i) res=res*seed+ord[str[i]]; return res;}void init(){ for(int i=‘a‘,j=1;i<=‘z‘;++i,++j) ord[i]=(ull)j; seeds[0]=1; for(int i=1;i<=minv;++i) seeds[i]=seeds[i-1]*seed;}bool Find(const int &o,const ull &x){ int y=(int)(x%MOD); for(VER it=List[o][y].begin();it!=List[o][y].end();++it) if(*it==x) return 1; return 0;}bool Find_In_All(const ull &x){ for(int i=1;i<=n;++i) if(i!=mini&&(!Find(i,x))) return 0; return 1;}bool check(const int &x){ for(int i=1;i<=n;++i) if(i!=mini) { ull hs=BKDRhash(s[i],0,x); List[i][hs%MOD].push_back(hs); for(int j=x;j<ls[i];++j) { hs=hs*seed+ord[s[i][j]]; hs-=seeds[x]*ord[s[i][j-x]]; List[i][hs%MOD].push_back(hs); } } ull hs=BKDRhash(s[mini],0,x); if(Find_In_All(hs)) return 1; for(int i=x;i<minv;++i) { hs=hs*seed+ord[s[mini][i]]; hs-=seeds[x]*ord[s[mini][i-x]]; if(Find_In_All(hs)) return 1; } return 0;}int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%s",s[i]); ls[i]=strlen(s[i]); if(ls[i]<minv) { minv=ls[i]; mini=i; } } init(); int l=0,r=minv+1; while(l<r) { int mid=l+r>>1; if(check(mid)) l=mid+1; else r=mid; } printf("%d\n",l-1); return 0;}
【二分答案】【哈希表】【字符串哈希】bzoj2946 [Poi2000]公共串
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。