BZOJ 4084 [Sdoi2015]双旋转字符串
生活随笔
收集整理的這篇文章主要介紹了
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; }
轉載于:https://www.cnblogs.com/zzyer/p/8505531.html
總結
以上是生活随笔為你收集整理的BZOJ 4084 [Sdoi2015]双旋转字符串的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 取消忘记密码的excel文件的保护
- 下一篇: 手游服务端开发