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

题目大意:

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

分析:

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

代码如下:

 #include <bits/stdc++.h>
using namespace std; #define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define rFor(i,t,s) for (int i = (t); i >= (s); --i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i) #define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl #define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin()) #define ms0(a) memset(a,0,sizeof(a))
#define msI(a) memset(a,inf,sizeof(a)) #define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair
#define pb push_back
#define fi first
#define se second inline int gc(){
static const int BUF = 1e7;
static char buf[BUF], *bg = buf + BUF, *ed = bg; if(bg == ed) fread(bg = buf, , BUF, stdin);
return *bg++;
} inline int ri(){
int x = , f = , c = gc();
for(; c<||c>; f = c=='-'?-:f, c=gc());
for(; c>&&c<; x = x* + c - , c=gc());
return x*f;
} typedef long long LL;
typedef unsigned long long uLL;
const LL mod = 1e9 + ;
const int maxN = + ; string T, Sbeg, Sed;
unordered_set< LL > sll;
int beg[maxN], begLen; // 记录 Sbeg出现的位置
int ed[maxN], edLen; // 记录 Sed出现的位置 // h为T的后缀哈希数组
// h[i]表示T从i位置开始的后缀的哈希值
// h[i] = T[i] + T[i+1]*key + T[i+2]*key^2 + ……+ T[i+len-1-i]*key^len-1-i
// xp为基数数组
// xp[i] = key^i
LL xp[maxN], h[maxN];
const LL key = 1e9 + ; // 求起点为s,长为len的子串的哈希值
// Hash(i, len) = T[i] + T[i+1]*key + T[i+2]*key^2 + ……+ T[i+len-1]*key^len-1
LL Hash(int s, int len) {
return h[s] - h[s + len] * xp[len];
} void HashInit(const char* s, LL* h, int len) {
xp[] = ;
For(i, , maxN - ) xp[i] = xp[i - ] * key; h[len] = ;
rFor(i, len - , ) h[i] = h[i + ] * key + s[i];
} int main(){
while(cin >> T >> Sbeg >> Sed) {
HashInit(T.c_str(), h, (int)T.size()); int ans = ;
sll.clear();
begLen = edLen = ; int p = ;
while(p < T.size()) {
int t = T.find(Sbeg.c_str(), p);
if(t == string::npos) break;
beg[begLen++] = t;
p = t + ;
} p = ;
while(p < T.size()) {
int t = T.find(Sed.c_str(), p);
if(t == string::npos) break;
ed[edLen++] = t;
p = t + ;
} int i = , j = ;
while(i < begLen && j < edLen) {
if(beg[i] <= ed[j]) {
For(k, j, edLen - ) {
if(beg[i] + Sbeg.size() > ed[k] + Sed.size()) continue;
sll.insert(Hash(beg[i], ed[k] + Sed.size() - beg[i]));
}
++i;
}
else ++j;
} cout << sll.size() << endl;
}
return ;
}

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. Linux平台上轻松安装与配置Domino

    Linux平台上轻松安装与配置Domino Domino Server的编译安装过程中需要用到libstdc++-2.9和glibc-2.1.1(或者其更高的版本)两个编译模块,它们是Linux开发编 ...

  2. [tool] google搜索的正确使用姿势(待补全)

    第一,也是非常重要的前提,请一定要能FQ.如果这条没有解决,没有往下的必要 现在我假设你已经能FQ了,个人推荐使用搜索引擎的顺序: Google>微软bing国际搜索>百度 (百度总能给你 ...

  3. 【LOJ 2144】「SHOI2017」摧毁「树状图」

    LOJ 2144 84pts 首先\(op2\)很简单.直接并查集一搞就好了(话说我现在什么东西都要写个并查集有点...) 然后\(op0\)我不会,就直接\(O(n^2)\)枚举一下\(P\)这个人 ...

  4. SkylineGlobe系列软件对机器配置要求

    6.6版本: TerraExplorer for Desktop / Web Operating System: Windows® 7/ 8/ 10 - 64 bit recommended Proc ...

  5. Charles 抓包工具安装和采坑记录

    Charles 抓包工具安装和采坑记录 网络抓包是解决网络问题的第一步,也是网络分析的基础.网络出现问题,第一步肯定是通过抓包工具进行路径分析,看哪一步出现异常.做网络爬虫,第一步就是通过抓包工具对目 ...

  6. NLP基础——词集模型(SOW)和词袋模型(BOW)

    (1)词集模型(Set Of Words): 单词构成的集合,集合自然每个元素都只有一个,也即词集中的每个单词都只有一个. (2)词袋模型(Bag Of Words): 如果一个单词在文档中出现不止一 ...

  7. wtf_1234

    好无聊啊,今天困的厉害. 不想做任何事情 wtf bitch!

  8. Python-每日习题-0009-time

    题目:暂停一秒输出 程序分析:使用 time 模块的 sleep() 函数. import time for i in range(4): print(str(int(time.time()))[-2 ...

  9. H5 id选择器

    09-id选择器 迟到毁一生 早退穷三代 按时上下班 必成高富帅 <!DOCTYPE html> <html lang="en"> <head> ...

  10. 小小知识点(二)——如何修改win10 的C盘中用户下的文件夹名称

    1.以管理员身份登录计算机 在win10桌面的开始界面处有个用户头像,点击在里面找到administrator: 如果没有,则需进行如下设置: (1)右键计算机,双击管理,找到如下所示的用户中的adm ...