BZOJ 4084 [Sdoi2015]双旋转字符串
题解:hash
至今不会unsigned long long 的输出
把B扔进map
找A[mid+1][lenA]在A[1][mid]中的位置
把A[1][mid]贴两遍(套路)
枚举A[mid+1][lenA]在A[1][mid]中出现的位置,把其他位置的hash值求出来,在map里查有多少符合的B串
#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<algorithm> using namespace std; const int maxn=8000009; typedef unsigned long long uLint; int n,m,lenA,lenB,mid; char s[maxn]; long long ans; int r; uLint h[maxn]; uLint fac[maxn]; map<uLint,int>ma; uLint a[maxn]; void Addstring(){ int cnt=0; uLint midstring=0; for(int i=mid+1;i<=lenA;++i)midstring=midstring*233+s[i]; for(int i=1;i<=mid;++i)s[i+mid]=s[i]; h[0]=0; for(int i=1;i<=mid+mid;++i)h[i]=h[i-1]*233+s[i]; for(int i=1;i<=mid;++i){ uLint tm=h[i+r-1]-h[i-1]*fac[r]; if(tm!=midstring)continue; a[++cnt]=h[i+mid-1]-h[i+r-1]*fac[mid-r]; } sort(a+1,a+1+cnt); cnt=unique(a+1,a+1+cnt)-a-1; for(int i=1;i<=cnt;++i)ma[a[i]]++; } int main(){ scanf("%d%d%d%d",&n,&m,&lenA,&lenB); fac[0]=1; for(int i=1;i<=lenA+lenA;++i)fac[i]=fac[i-1]*233; mid=(lenA+lenB)>>1; r=lenA-mid; while(n--){ scanf("%s",s+1); Addstring(); } while(m--){ scanf("%s",s+1); uLint tm=0; for(int i=1;i<=lenB;++i)tm=tm*233+s[i]; ans=ans+ma[tm]; } cout<<ans<<endl; return 0; }
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!