双旋转字符串 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相关推荐

  1. 4084: [Sdoi2015]双旋转字符串

    4084: [Sdoi2015]双旋转字符串 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 394  Solved: 161 [Submit][St ...

  2. 【BZOJ】4084: [Sdoi2015]双旋转字符串 哈希

    传送门:bzoj4084 题解 题面非常坑!!! 要求的是Si+TjSi+TjS_i+T_j,但实际上任意Tj+SiTj+SiT_j+S_i也可以算. AC的程序跑出的两组数据: input: 1 1 ...

  3. BZOJ 4084 [Sdoi2015]双旋转字符串

    题解:hash 至今不会unsigned long long 的输出 把B扔进map 找A[mid+1][lenA]在A[1][mid]中的位置 把A[1][mid]贴两遍(套路) 枚举A[mid+1 ...

  4. 【bzoj4084】【sdoi2015】双旋转字符串

    题解 首先题中说了$n>=m$; 分成的循环串左右两边为本质相同的单循环串循环串,分别长为$l = \frac{n + m}{2} $; 所以$S$串的前$l$位为双循环串的一半$S1$,后一半 ...

  5. bzoj 4084 双旋转字符串

    给两个集合A,B,找满足要求的(a,b)的对数,可以计算对于a,哪些b成立. 还有就是字符串hash的使用,感觉平时用字符串hash太少了. 1 /************************** ...

  6. 代码随想录算法训练营第八天|344.反转字符串 541. 反转字符串II 剑指Offer 05.替换空格 151.翻转字符串里的单词 剑指Offer58-II.左旋转字符串

    一.344.反转字符串 题目:编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 char[] 的形式给出. 不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的 ...

  7. 【编程题目】左旋转字符串 ☆

    26.左旋转字符串(字符串) 题目: 定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部. 如把字符串 abcdef 左旋转 2 位得到字符串 cdefab.请实现字符串左旋转的函数. ...

  8. 经典算法面试题目-判断s2是否是s1的旋转字符串(1.8)

    题目 Assume you have a method isSubstring which checks if one word is a substring of another. Given tw ...

  9. 【剑指offer-Java版】42翻转单词顺序VS左旋转字符串

    反转单词顺序以及左旋转字符串:输入一个英文句子,翻转句子中的单词顺序,单词内部的字母顺序是不变的 – I am a student. -> student. am I 第一步,翻转句子中的所有字 ...

最新文章

  1. R语言dplyr包移除dataframe数据列实战(Remove Columns)
  2. ADS1.2安装教程
  3. ios开发中计算代码运算时间_iOS日历、日期、时间的计算
  4. C++ STL库的总结以及实现原理
  5. 函数||值传递||函数的常见样式||函数的声明||函数的分文件编写
  6. element ui点击按钮弹出款_前端猿应该知道的十大最流行的前端UI框架
  7. Scala基础教程(二):数据类型、变量
  8. About 磁珠(Bead)
  9. 思维导图 源码 php,使用思维导图,优雅的完成自己的代码
  10. Reids 批量删除有相同前缀的keys
  11. 计算机软件著作权的保护范围,计算机软件的著作权保护范围分析
  12. servlet跳转问题
  13. Lucene Automaton(二)
  14. stata17安装教程
  15. 在线购物系统——设计类
  16. 2021-1-16-JavaGuide老哥的操作系统常见问题总结 自己按照理解,综合了王道考研的视频,对内容进行了修改,增加了内容,以便于自己理解。这份材料不是背的,而是让自己去理解的。
  17. 下厨房(istringstream的使用)----网易2017内推笔试编程题合集
  18. Thinkpad E450c进入BIOS
  19. 安卓Bmob后端云的使用(增删改查、上传图片、推送服务等)
  20. 计算机培训软文,软文诊断62期: 学写软文标题,只需懂电脑开机即可

热门文章

  1. 【转】Win7 更改文件夹背景
  2. OA系统和ERP有什么区别?
  3. UTF-8与UTF-8(BOM)区别和一些说明
  4. 某银行大数据体系架构设计与演进
  5. 叶史瓦大学计算机专业,叶史瓦的大学排名
  6. 提车二月记--小鹏P7
  7. 使用高级语言编写计算机程序步骤,计算机执行用高级语言编写的程序主要有两种途径解释和编译编译专.doc...
  8. AdaCliP: Adaptive Clipping for Private SGD
  9. 锐捷服务器无线认证配置,【WLAN从入门到精通之对接案例】配置802.1X认证示例_Web(锐捷SAM服务器)...
  10. 一个人的赛道——天数智芯在AI计算领域的突围