给两个集合A,B,找满足要求的(a,b)的对数,可以计算对于a,哪些b成立.

还有就是字符串hash的使用,感觉平时用字符串hash太少了.

  1. /**************************************************************
  2. Problem: 4084
  3. User: idy002
  4. Language: C++
  5. Result: Accepted
  6. Time:6456 ms
  7. Memory:290272 kb
  8. ****************************************************************/
  9.  
  10. #include <cstdio>
  11. #include <set>
  12. #include <vector>
  13. #include <algorithm>
  14. #define N 8000010
  15. #define Base 31
  16. #define Mod 1000000007
  17. using namespace std;
  18.  
  19. typedef long long dnt;
  20.  
  21. int n, m, ln, lm;
  22. char *sa[N], *sb[N];
  23. char buf_arr[N], *buf=buf_arr;
  24. dnt fx[N], sx[N], pow[N];
  25. int fail[N];
  26. multiset<int> stb;
  27.  
  28. int hash( char *s ) {
  29. dnt rt = ;
  30. for( int i=; s[i]; i++ )
  31. rt = (rt*Base + s[i]-'a') % Mod;
  32. return rt;
  33. }
  34. void init_hash( int ln, char *s ) { // ln>=1
  35. fx[] = s[]-'a';
  36. for( int j=; j<ln; j++ )
  37. fx[j] = (fx[j-]*Base + s[j]-'a') % Mod;
  38. sx[ln-] = s[ln-]-'a';
  39. for( int j=ln-; j>=; j-- )
  40. sx[j] = ((s[j]-'a')*pow[ln--j] + sx[j+]) % Mod;
  41. }
  42. void init_fail( char *s ) {
  43. fail[] = ;
  44. fail[] = ;
  45. for( int i=; s[i]; i++ ) {
  46. int j=fail[i];
  47. while( j && s[j]!=s[i] ) j=fail[j];
  48. if( s[j]==s[i] )
  49. fail[i+]=j+;
  50. else
  51. fail[i+]=;
  52. }
  53. }
  54. void work1() { // ln > lm
  55. vector<int> vc;
  56. int ll = (ln+lm)>>;
  57. dnt ans = ;
  58. for( int t=; t<=n; t++ ) {
  59. init_fail(sa[t]+ll);
  60. for( int i=; i<ll; i++ )
  61. buf[i] = sa[t][i];
  62. for( int i=; i<ll; i++ )
  63. buf[ll+i] = sa[t][i];
  64. init_hash(ll+ll,buf);
  65. vc.clear();
  66. int i=, j=;
  67. while( i<ln- ) {
  68. while( i<ln- && j<ln-ll && buf[i]==sa[t][ll+j] ) i++, j++;
  69. if( j==ln-ll ) {
  70. dnt v;
  71. v = fx[i+(ll+ll-ln)-]-fx[i-]*pow[ll+ll-ln];
  72. v = (v%Mod+Mod) % Mod;
  73. vc.push_back(v);
  74. j = fail[ln-ll];
  75. }
  76. if( i==ln- ) break;
  77. while( j && sa[t][ll+j]!=buf[i] ) j=fail[j];
  78. if( sa[t][ll+j]!=buf[i] ) i++;
  79. }
  80. sort( vc.begin(), vc.end() );
  81. vc.erase( unique(vc.begin(),vc.end()), vc.end() );
  82. for( int t=; t<vc.size(); t++ )
  83. ans += stb.count(vc[t]);
  84. }
  85. printf( "%lld\n", ans );
  86. }
  87. void work3() { // ln = lm
  88. vector<int> vc;
  89. dnt ans = ;
  90. for( int i=; i<=n; i++ ) {
  91. init_hash(ln,sa[i]);
  92. vc.clear();
  93. vc.push_back( sx[] );
  94. for( int j=; j<ln; j++ ) {
  95. int v = ((dnt)sx[j]*pow[j]+fx[j-]) % Mod;
  96. vc.push_back(v);
  97. }
  98. sort( vc.begin(), vc.end() );
  99. vc.erase( unique(vc.begin(), vc.end()), vc.end() );
  100. for( int t=; t<vc.size(); t++ )
  101. ans += stb.count(vc[t]);
  102. }
  103. printf( "%lld\n", ans );
  104. }
  105. int main() {
  106. scanf( "%d%d%d%d", &n, &m, &ln, &lm );
  107. if( ln>lm ) {
  108. for( int i=; i<=n; i++ ) {
  109. scanf( "%s", buf );
  110. sa[i] = buf;
  111. buf += ln+;
  112. }
  113. for( int i=; i<=m; i++ ) {
  114. scanf( "%s", buf );
  115. sb[i] = buf;
  116. buf += lm+;
  117. }
  118. } else {
  119. swap(n,m);
  120. swap(ln,lm);
  121. for( int i=; i<=m; i++ ) {
  122. scanf( "%s", buf );
  123. sb[i] = buf;
  124. reverse( buf, buf+lm );
  125. buf += lm+;
  126. }
  127. for( int i=; i<=n; i++ ) {
  128. scanf( "%s", buf );
  129. sa[i] = buf;
  130. reverse( buf, buf+ln );
  131. buf += ln+;
  132. }
  133. }
  134. pow[] = ;
  135. for( int i=; i<=ln; i++ )
  136. pow[i] = pow[i-]*Base % Mod;
  137. for( int i=; i<=m; i++ )
  138. stb.insert( hash(sb[i]) );
  139. if( ln!=lm )
  140. work1();
  141. else
  142. work3();
  143. }

bzoj 4084 双旋转字符串的更多相关文章

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

    双旋转字符串 bzoj-4084 Sdoi-2015 题目大意:给定两个字符串集合 S 和 T .其中 S 中的所有字符串长度都恰好为 N ,而 T 中所有字符串长度都恰好为 M .且 N+M 恰好为 ...

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

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

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

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

  4. 剑指Offer面试题:34.翻转单词顺序VS左旋转字符串

    一.题目一:翻转单词顺序 1.1 题目说明 题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理.例如输入字符串"I am a st ...

  5. 【面试题042】翻转单词顺序VS左旋转字符串

    [面试题042]翻转单词顺序VS左旋转字符串 题目一:     输入一个英文句子,反转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理.     例如输入字符串“I a ...

  6. lintcode :旋转字符串

    题目: 旋转字符串 给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转) 样例 对于字符串 "abcdefg". offset=0 => "abcdef ...

  7. 九度OJ 1362 左旋转字符串(Move!Move!!Move!!!)【算法】

    题目地址:http://ac.jobdu.com/problem.php?pid=1362 题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运 ...

  8. LintCode 面试题 旋转字符串

    1.题目描述 题目链接:http://www.lintcode.com/zh-cn/problem/rotate-string/ 给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转) 2. ...

  9. 1289 大鱼吃小鱼 1305 Pairwise Sum and Divide 1344 走格子 1347 旋转字符串 1381 硬币游戏

    1289 大鱼吃小鱼 有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右.游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼.从左到右给出每条鱼的大小和游动的方向(0表示向左,1表示向右 ...

随机推荐

  1. Mashup

    简介 mashup是糅合,是当今网络上新出现的一种网络现象,将两种以上使用公共或者私有数据库的web应用,加在一起,形成一个整合应用.一般使用源应用的API接口,或者是一些rss输出(含atom)作为 ...

  2. python中对列表和循环使用的小练习

    #author devilf product_list = [ (), (), (), (), () ] shop_list = [] salary = input('pls enter your s ...

  3. 部署vCenter Server Appliance 6.7

    =============================================== 2019/4/14_第1次修改                       ccb_warlock == ...

  4. position:absolute在IE8浏览器下无法显示正确位置

      在网页head下添加 <meta http-equiv="x-ua-compatible" content="ie=8" />

  5. OCM_第五天课程:Section2 —》AGENT 的安装 、GC 的使用

    注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...

  6. SSD笔记

    参考:https://zhuanlan.zhihu.com/p/24954433?refer=xiaoleimlnote http://blog.csdn.net/u010167269/article ...

  7. windows10+mysql8.0.11zip安装

    准备: MySQL8.0 Windows zip包下载地址:https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.11-winx64.zip 环境: ...

  8. js数值进制互转

    十进制转换为二进制: var num = 100; console.log(num.toString(2)); toString()方法可把一个 Number 对象转换为一个字符串,并返回结果. 语法 ...

  9. MySQL表的定期分析检查优化

    Analyze Table 分析表   MySQL 的Optimizer(优化元件)在优化SQL语句时,首先需要收集一些相关信息,其中就包括表的cardinality(可以翻译为“散列程度”),它表示 ...

  10. whiledo循环输出数组中的分数

    var scores = [24, 32, 17]; var arrayLength = scores.length; var i =0; while(i < arrayLength){ var ...