题目链接:http://codeforces.com/problemset/problem/113/B

题目大意:

多组数据
每组给定3个字符串T,Sbeg,Sed,求字符串T中有多少子串是以Sbeg开头,Sed结尾的

分析:

  难点在哈希函数的编写,如果直接存string会爆内存,不能用STL自带哈希函数,用了会Wa。

代码如下:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define rep(i,n) for (int i = 0; i < (n); ++i)
  5. #define For(i,s,t) for (int i = (s); i <= (t); ++i)
  6. #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
  7. #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
  8. #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
  9.  
  10. #define pr(x) cout << #x << " = " << x << " "
  11. #define prln(x) cout << #x << " = " << x << endl
  12.  
  13. #define ALL(x) x.begin(),x.end()
  14. #define INS(x) inserter(x,x.begin())
  15.  
  16. #define ms0(a) memset(a,0,sizeof(a))
  17. #define msI(a) memset(a,inf,sizeof(a))
  18.  
  19. #define pii pair<int,int>
  20. #define piii pair<pair<int,int>,int>
  21. #define mp make_pair
  22. #define pb push_back
  23. #define fi first
  24. #define se second
  25.  
  26. inline int gc(){
  27. static const int BUF = 1e7;
  28. static char buf[BUF], *bg = buf + BUF, *ed = bg;
  29.  
  30. if(bg == ed) fread(bg = buf, , BUF, stdin);
  31. return *bg++;
  32. }
  33.  
  34. inline int ri(){
  35. int x = , f = , c = gc();
  36. for(; c<||c>; f = c=='-'?-:f, c=gc());
  37. for(; c>&&c<; x = x* + c - , c=gc());
  38. return x*f;
  39. }
  40.  
  41. typedef long long LL;
  42. typedef unsigned long long uLL;
  43. const LL mod = 1e9 + ;
  44. const int maxN = + ;
  45.  
  46. string T, Sbeg, Sed;
  47. unordered_set< LL > sll;
  48. int beg[maxN], begLen; // 记录 Sbeg出现的位置
  49. int ed[maxN], edLen; // 记录 Sed出现的位置
  50.  
  51. // h为T的后缀哈希数组
  52. // h[i]表示T从i位置开始的后缀的哈希值
  53. // h[i] = T[i] + T[i+1]*key + T[i+2]*key^2 + ……+ T[i+len-1-i]*key^len-1-i
  54. // xp为基数数组
  55. // xp[i] = key^i
  56. LL xp[maxN], h[maxN];
  57. const LL key = 1e9 + ;
  58.  
  59. // 求起点为s,长为len的子串的哈希值
  60. // Hash(i, len) = T[i] + T[i+1]*key + T[i+2]*key^2 + ……+ T[i+len-1]*key^len-1
  61. LL Hash(int s, int len) {
  62. return h[s] - h[s + len] * xp[len];
  63. }
  64.  
  65. void HashInit(const char* s, LL* h, int len) {
  66. xp[] = ;
  67. For(i, , maxN - ) xp[i] = xp[i - ] * key;
  68.  
  69. h[len] = ;
  70. rFor(i, len - , ) h[i] = h[i + ] * key + s[i];
  71. }
  72.  
  73. int main(){
  74. while(cin >> T >> Sbeg >> Sed) {
  75. HashInit(T.c_str(), h, (int)T.size());
  76.  
  77. int ans = ;
  78. sll.clear();
  79. begLen = edLen = ;
  80.  
  81. int p = ;
  82. while(p < T.size()) {
  83. int t = T.find(Sbeg.c_str(), p);
  84. if(t == string::npos) break;
  85. beg[begLen++] = t;
  86. p = t + ;
  87. }
  88.  
  89. p = ;
  90. while(p < T.size()) {
  91. int t = T.find(Sed.c_str(), p);
  92. if(t == string::npos) break;
  93. ed[edLen++] = t;
  94. p = t + ;
  95. }
  96.  
  97. int i = , j = ;
  98. while(i < begLen && j < edLen) {
  99. if(beg[i] <= ed[j]) {
  100. For(k, j, edLen - ) {
  101. if(beg[i] + Sbeg.size() > ed[k] + Sed.size()) continue;
  102. sll.insert(Hash(beg[i], ed[k] + Sed.size() - beg[i]));
  103. }
  104. ++i;
  105. }
  106. else ++j;
  107. }
  108.  
  109. cout << sll.size() << endl;
  110. }
  111. return ;
  112. }

CodeForces 113B Petr#的更多相关文章

  1. CodeForces - 113B Petr# (后缀数组)

    应该算是远古时期的一道题了吧,不过感觉挺经典的. 题意是给出三一个字符串s,a,b,求以a开头b结尾的本质不同的字符串数. 由于n不算大,用hash就可以搞,不过这道题是存在复杂度$O(nlogn)$ ...

  2. 【Codeforces 113B】Petr#

    Codeforces 113 B 题意:有一个母串\(S\)以及两个串\(S_{begin}\)和\(S_{end}\),问\(S\)中以\(S_{begin}\)为开头并且以\(S_{end}\)为 ...

  3. Codeforces 113B

    题目链接 B. Petr# time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  4. Codeforces 987E Petr and Permutations(数组的置换与复原 、结论)

    题目连接: Petr and Permutations 题意:给出一个1到n的序列,Petr打乱了3n次,Um_nik打乱了7n+1次,现在给出被打乱后的序列,求是谁打乱的. 题解:因为给出了一个3* ...

  5. CodeForces - 987E Petr and Permutations (思维+逆序对)

    题意:初始有一个序列[1,2,...N],一次操作可以将任意两个位置的值互换,Petr做3*n次操作:Alxe做7*n+1次操作.给出最后生成的新序列,问是由谁操作得到的. 分析:一个序列的状态可以归 ...

  6. Codeforces 760A Petr and a calendar

    题目链接:http://codeforces.com/problemset/problem/760/A 题意:日历需要多少列. #include <bits/stdc++.h> using ...

  7. Codeforces 986B. Petr and Permutations(没想到这道2250分的题这么简单,早知道就先做了)

    这题真的只能靠直觉了,我没法给出详细证明. 解题思路: 1.交换3n次或者7n+1次,一定会出现一个为奇数,另一个为偶数. 2.用最朴素的方法,将n个数字归位,计算交换次数. 3.判断交换次数是否与3 ...

  8. Codeforces 986B - Petr and Permutations

    Description\text{Description}Description Given an array a[], swap random 2 number of them for 3n or  ...

  9. codeforces982F

    The Meeting Place Cannot Be Changed CodeForces - 982F Petr is a detective in Braginsk. Somebody stol ...

随机推荐

  1. 洛谷P2845-Switching on the Lights 开关灯

    Problem 洛谷P2845-Switching on the Lights 开关灯 Accept: 154    Submit: 499Time Limit: 1000 mSec    Memor ...

  2. 《JAVA程序设计》_第二周学习总结

    20175217吴一凡 一.IDEA的安装和使用 参考老师的教程Intellj IDEA 简易教程. 1.IDEA的安装 因为我已经习惯了在Linux上敲代码,所以我决定将IDEA安装在虚拟机上. 首 ...

  3. linux上安装完torch后仍报错:ImportError: No module named torch

    linux上安装完torch后仍报错: Traceback (most recent call last): File , in <module> import torch ImportE ...

  4. go第三方日志系统-seelog-使用文档

    参考:https://godoc.org/github.com/cihub/seelog 导入方式: import "github.com/cihub/seelog" 包seelo ...

  5. Python+Pycharm—学习—pip

    1.pip是干什么的? 2.pip怎么安装? 3.pip怎么用?

  6. 初学Python——面向对象编程

    一.面向对象 or 面向过程? 编程范式: 编程是 程序 员 用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程 , 一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所 ...

  7. 数组升序排序的方法Arrays.sort();的应用

    package com.Summer_0421.cn; import java.util.Arrays; /** * @author Summer * 数组升序排序的方法Arrays.sort();应 ...

  8. 5238-整数校验器-洛谷3月赛gg祭

    传送门 题目描述 有些时候需要解决这样一类问题:判断一个数 x是否合法. x合法当且仅当其满足如下条件: x格式合法,一个格式合法的整数要么是 0,要么由一个可加可不加的负号,一个 1到 9 之间的数 ...

  9. Intellij Idea 2017创建web项目及tomcat部署实战

    相关软件:Intellij Idea2017.jdk16.tomcat7 Intellij Idea直接安装(可根据需要选择自己设置的安装目录),jdk使用1.6/1.7/1.8都可以,主要是配置好系 ...

  10. UVA - 10931-Parity

    题意:1.输入一个数,将其转换为二进制.2.记录二进制中出现1的次数. 注意:转换二进制后直接输出,不能转换为十进制后输出 #include<iostream> #include<c ...