日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[bzoj4084][Sdoi2015]双旋转字符串_hash

發布時間:2023/12/8 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [bzoj4084][Sdoi2015]双旋转字符串_hash 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

雙旋轉字符串 bzoj-4084 Sdoi-2015

題目大意:給定兩個字符串集合 S 和 T 。其中 S 中的所有字符串長度都恰好為 N ,而 T 中所有字符串長度都恰好為 M 。且 N+M 恰好為偶數。如果記 S 中字符串全體為 S1,S2,...,STotalS ,而 T 中字符串全體為 T1,T2,...,TTotalT 。現在希望知道有多少對 <i,j> ,滿足將 Si 和 Tj 拼接后得到的字符串 Si+Tj 滿足雙旋轉性。一個長度為偶數字符串 W 可以表示成兩段長度相同的字符串的拼接,即W=U+V。如果 V 可以通過 U 旋轉得到,則稱 W 是滿足雙旋轉性的。比如說字符串 U=“vijos”可以通過旋轉得到“ijosv”,“josvi”,“osvij” 或“svijo”。那么“vijosjosvi”就是滿足雙旋轉性的字符串。

想法:我們將小的集合所有串hash然后存起來,這一步是容易的。對于大串我們將他所有旋轉后的前(len1-mid)也存起來,這里只需要將每一個大串在尾部copy一遍,然后hash前綴和即可。mid的意思就是大、小串的長度平均值。然后暴力枚舉匹配即可。

最后,附上丑陋的代碼... ...

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #define N 8000010 using namespace std; typedef unsigned long long ull; ull h[N],g[N],f[N]; map<ull,int>MP; char s[N]; int ans; const int base=233; int n,m,S,T,k,mid; void find() {ull x=0;int cnt=0;for(int i=mid+1;i<=n;i++) x=x*base+s[i];for(int i=1;i<=mid;i++) s[i+mid]=s[i];for(int i=1;i<=mid*2;i++) f[i]=f[i-1]*base+s[i];for(int i=1;i<=mid;i++){ull y=f[i+k-1]-f[i-1]*h[k];if(y!=x) continue;g[++cnt]=f[i+mid-1]-f[i+k-1]*h[mid-k];}sort(g+1,g+cnt+1);for(int i=1;i<=cnt;i++) if(g[i]!=g[i-1]) MP[g[i]]++; } int main() {scanf("%d%d%d%d",&S,&T,&n,&m);h[0]=1;for(int i=1;i<=n+m;i++) h[i]=h[i-1]*base;mid=(n+m)>>1;k=n-mid;for(int i=1;i<=S;i++){scanf("%s",s+1);find();}for(int i=1;i<=T;i++){scanf("%s",s+1);ull x=0;for(int j=1;j<=m;j++) x=x*base+s[j];ans+=MP[x];}printf("%d",ans); }

?

小結:map真好用...hash真強... ...

轉載于:https://www.cnblogs.com/ShuraK/p/9333133.html

總結

以上是生活随笔為你收集整理的[bzoj4084][Sdoi2015]双旋转字符串_hash的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。