• 字符串_哈希


     参考文章:

    E. Compress Words(字符串hash)_z听歌的小孩z的博客-CSDN博客

    字符串哈希 - OI Wiki (oi-wiki.org)

    板子:

    1. #include
    2. using namespace std;
    3. const int N=2e4+50;
    4. typedef long long ll;
    5. const int mod=1e9+7;
    6. typedef unsigned long long ull;
    7. char s[N];
    8. int n;
    9. ll h[N],p[N],base=31;
    10. void init(){
    11. p[0]=1;
    12. for(int i=1;i<=n;i++){
    13. h[i]=(h[i-1]*base%mod+s[i])%mod;
    14. p[i]=p[i-1]*base%mod;
    15. }
    16. }
    17. int get_v(int l,int r){
    18. return ((h[r]-h[l-1]*p[r-l+1]%mod)%mod+mod)%mod;
    19. }
    20. int main(){
    21. scanf("%s",s+1);
    22. n=strlen(s+1);
    23. init();
    24. return 0;
    25. }
    26. /*
    27. ll p[3][N],h[3][N];
    28. ll mod[3]={100000007,998244353,100000009},base[3]={73,87,61};
    29. */

    例题: 

    例1:2021_ICPC_山东 F- Birthday Cake - Codeforces(双哈希)

    题解: 

    看一个字符串的前缀和后缀,如果这两个前后缀相等,就去查询这个字符串除去这个前后缀之后还剩下的部分是否出现过,然后统计出现次数的答案 ps 我们把所有串按照串的长度从小到大排个序,一定要排,不然aaaa,aa这个数据就可以卡掉。 

    1. /*
    2. eg:abcabcd
    3. l=7 j=3 r=l-j+1=5
    4. 前缀[1,3] 后缀[5,7]
    5. chk(1,3)==chk(5,7)
    6. chk(4,6)
    7. */
    1. #include
    2. using namespace std;
    3. const int N=4e5+5;
    4. typedef long long ll;
    5. typedef pair pi;
    6. const ll mod1=1e9+7,mod2=1e9+9;
    7. string s[N];
    8. char ss[N];
    9. int n;
    10. ll res;
    11. bool cmp(string x,string y){
    12. return x.length()length();
    13. }
    14. ll p1[N],p2[N],h1[N],h2[N],P=31;
    15. void init(){
    16. p1[0]=p2[0]=1;
    17. for(int i=1;i
    18. p1[i]=p1[i-1]*P%mod1,p2[i]=p2[i-1]*P%mod2;
    19. }
    20. void get_h(int n){
    21. for(int i=1;i<=n;i++){
    22. h1[i]=(h1[i-1]*P%mod1+ss[i])%mod1;
    23. h2[i]=(h2[i-1]*P%mod2+ss[i])%mod2;
    24. }
    25. }
    26. ll getv1(int l,int r){
    27. return (h1[r]-h1[l-1]*p1[r-l+1]%mod1+mod1)%mod1;
    28. }
    29. ll getv2(int l,int r){
    30. return (h2[r]-h2[l-1]*p2[r-l+1]%mod2+mod2)%mod2;
    31. }
    32. mapint>mp;
    33. int main(){
    34. init();
    35. scanf("%d",&n);
    36. for(int i=1;i<=n;i++)cin>>s[i];
    37. sort(s+1,s+1+n,cmp);
    38. for(int i=1;i<=n;i++){
    39. int len=s[i].length();
    40. for(int j=0;j1]=s[i][j];
    41. get_h(len);
    42. //前缀==后缀
    43. for(int j=1;j1;j++){//[1,j][r,len]
    44. int r=len-j+1;
    45. if(getv1(1,j)==getv1(r,len)&&getv2(1,j)==getv2(r,len)){
    46. //除去前后缀的部分 [j+1,r-1]
    47. res+=mp[{getv1(j+1,r-1),getv2(j+1,r-1)}];
    48. }
    49. }ll v1=getv1(1,len),v2=getv2(1,len);//printf("end");
    50. //printf("i:%d [1,%d] [%d,%d] res%d\n",i,j,r,len,res);
    51. //printf("v1 %lld v2 %lld\n",v1,v2);
    52. res+=mp[{v1,v2}];
    53. mp[{v1,v2}]++;
    54. //printf("i:%d [1,%d] [%d,%d] res%d\n",i,j,r,len,res);
    55. }printf("%lld",res);
    56. return 0;
    57. }

    例2:E - Compress Words- Codeforces(双哈希)

    题解:从长到短枚举每一个单词的前缀,和前面的所有单词匹配

    *单哈希会被卡

    *必须和前面所有单词匹配,不能只和前一个单词匹配

    1. #include
    2. using namespace std;
    3. const int N=1e6+5;
    4. typedef long long ll;
    5. typedef unsigned long long ull;
    6. typedef pair pi;
    7. const ll mod[2]={100000007,100000009};
    8. int n,cnt;
    9. char s[N],ss[N];
    10. ll h1[3][N],h2[3][N],p[3][N],P[3]={73,87,61};
    11. int l1,l2;
    12. inline void init(){
    13. p[0][0]=p[1][0]=p[2][0]=1;
    14. for(int k=0;k<2;k++)
    15. for(int i=1;i-1]*P[k])%mod[k];
    16. }
    17. inline void geth(int n,int num){
    18. for(int j=0;j
    19. for(int i=1;i<=n;i++)
    20. h1[j][i]=((h1[j][i-1]*P[j])%mod[j]+s[i])%mod[j];
    21. }
    22. inline ll getv2(int l,int r,int i){
    23. return ((h2[i][r]-(h2[i][l-1]*p[i][r-l+1])%mod[i])%mod[i]+mod[i])%mod[i];
    24. }
    25. int main(){
    26. init();
    27. scanf("%d",&n);
    28. for(int i=1;i<=n;i++){
    29. scanf("%s",s+1);
    30. l1=strlen(s+1);
    31. //printf("i%d %s l1:%d\n",i,s+1,l1);
    32. geth(l1,2);
    33. int anj=1;
    34. //printf("l2:%d l1:%d l2-l1+1:%d\n",l2,l1,l2-l1+1);
    35. int j1=l1,j2=l2-l1+1;
    36. if(j2<1)j1+=j2-1,j2=1;
    37. for(;j1>0&&j2<=l2;j1--,j2++){
    38. //printf("[1,%d]%lld [%d,%d]%lld %lld %lld %lld %lld\n",j1,h1[0][j1],j2,l2,getv2(j2,l2,0),h1[1][j1],getv2(j2,l2,1),h1[2][j1],getv2(j2,l2,2));
    39. if(h1[0][j1]==getv2(j2,l2,0)&&h1[1][j1]==getv2(j2,l2,1)){
    40. anj=j1+1;
    41. //printf("anj %d\n",anj);
    42. break;
    43. }
    44. }
    45. int t=cnt;
    46. for(int j=anj;j<=l1;j++)ss[++cnt]=s[j];
    47. //printf("cnt%d %s\n",cnt,ss+1);
    48. for(int j=0;j<2;j++)
    49. for(int i=t;i<=cnt;i++)
    50. h2[j][i]=((h2[j][i-1]*P[j])%mod[j]+ss[i])%mod[j];
    51. l2=cnt;
    52. }printf("%s",ss+1);
    53. return 0;
    54. }
  • 相关阅读:
    Vue源码学习(十九):router基本原理
    Vue中的事件监听
    IOS Swift 从入门到精通: 结构体的访问控制、静态属性和惰性
    React 使用echarts绘制滚动圆图,底部文字竖直放置
    ThreadLocal巨坑!内存泄露只是小儿科
    【JAVA进阶篇教学】第三篇:JDK8中Stream API使用
    基于元模型优化算法的主从博弈多虚拟电厂动态定价和能量管理MATLAB程序
    多目标应用:基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度(MATLAB)
    SOME/IP
    安装Zookeeper以及Kafka(CentOS7)
  • 原文地址:https://blog.csdn.net/m0_63851154/article/details/133188351