题目链接: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. C#事件の事件解析

    事件(event)是基于windows消息处理机制的类,封装的更好,让开发者无须知道底层的消息处理机制,就可以开发出强大的基于事件的应用程序来.委托(delegate)委托可以理解成为函数指针,不同的 ...

  2. 使用 vagrant新建Linux虚拟机

    准备工作 1.下载软件 2.安装软件 2.1 安装VirtualBox-5.1.34-121010-Win.exe 2.2 安装vagrant_2.0.3_x86_64.msi 3.新建 执行指令D: ...

  3. win10 激活(亲测可用)

    转自http://www.ylmfwin100.com/ylmf/8643.html 1.以管理员身份运行命令行(这一步一定要做) 2.依次输入以下命令 slmgr.vbs /upk (此时弹出窗口显 ...

  4. Python之Requests库的异常

    异常                        说明                                     requests.ConnectionError 网络链接错误一场,如 ...

  5. flask-sqlalchemy 一对一,一对多,多对多操作

    先进行如下操作: from flask import Flask from flask.ext.sqlalchemy import SQLAlchemy app=Flask(__name__) db= ...

  6. Python框架学习之用Flask创建一个简单项目

    在前面一篇讲了如何创建一个虚拟环境,今天这一篇就来说说如何创建一个简单的Flask项目.关于Flask的具体介绍就不详细叙述了,我们只要知道它非常简洁.灵活和扩展性强就够了.它不像Django那样集成 ...

  7. 【转】打包 压缩 命令tar zip

    https://www.cnblogs.com/centos2017/p/7896807.html tar语法 #压缩tar -czvf ***.tar.gztar -cjvf ***.tar.bz2 ...

  8. 从Linux内核角度看中间人攻击(ARP欺骗)并利用Python scapy实现

    邻居子系统与ARP协议 邻居子系统的作用就是将IP地址,转换为MAC地址,类似操作系统中的MMU(内存管理单元),将虚拟地址,转换为物理地址. 其中邻居子系统相当于地址解析协议(IPv4的ARP协议, ...

  9. Python脱产8期 Day06 2019/4/18

    一 深浅拷贝 例:ls = [1, 'abc', [10]] 1.值拷贝:s1 = ls    # ls1直接将ls中存放的地址拿过来,>ls内部的值发生任何变化,ls1都会随之变化. 2.浅拷 ...

  10. c# WPF RichTextBox 文字颜色

    public MainWindow() { InitializeComponent(); Run run = new Run("This is my text"); run.For ...