HDU 6153 A Secret(扩展KMP模板题)
A Secret
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Others)
Total Submission(s): 2523 Accepted Submission(s): 934
Suffix(S2,i) = S2[i...len].Ni is the times that Suffix(S2,i) occurs in S1 and Li is the length of Suffix(S2,i).Then the secret is the sum of the product of Ni and Li.
Now SF wants you to help him find the secret.The answer may be very large, so the answer should mod 1000000007.
The first line contains an integer T,the number of cases.Then following T cases.
Each test case contains two lines.The first line contains a string S1.The second line contains a string S2.
1<=T<=10.1<=|S1|,|S2|<=1e6.S1 and S2 only consist of lowercase ,uppercase letter.
The answer may be very large, so the answer should mod 1e9+7.
case 2:
Suffix(S2,1) = "aba",
题目链接:HDU 6153
扩展KMP解决的是对于每一个每一个$S$的后缀$Suffix(i)$,它与$T$串最长的公共前缀是多少,即它与$T$串各自从头开始能匹配几个,一旦有一个不匹配即结束。
这题求的是每一个$S_2$的后缀出现在$S_1$有几次,那么我们可以把两个串都反过来变成求$S_2$的前缀在$S_1$出现过几次,这样就可以发现如果$S_2$的前缀$prefix(j)$与$S_1$的后缀$Suffix(i)$的最长公共前缀为$k$,那么包括$prefix(j)$以及$j$以前的前缀均在$S_1$的$i$处出现过一次,贡献为$(k+1)*k/2$,那么这样求一遍$extend[]$数组后统计答案即可
代码:
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 1e6 + 7;
const LL mod = 1000000007LL;
char s[N], t[N];
int nxt[N], ex[N]; void getnxt(char T[], int len, int nxt[])
{
nxt[0] = len;
int a;
int p;
for (int i = 1, j = -1; i < len; i++, j--)
{
if (j < 0 || i + nxt[i - a] >= p)
{
if (j < 0)
p = i, j = 0;
while (p < len && T[p] == T[j])
p++, j++;
nxt[i] = j;
a = i;
}
else
nxt[i] = nxt[i - a];
}
}
void getextend(char S[], char T[], int ls, int lt, int extend[], int nxt[])
{
getnxt(T, lt, nxt); //得到next
int a;
int p; //记录匹配成功的字符的最远位置p,及起始位置a
for (int i = 0, j = -1; i < ls; i++, j--) //j即等于p与i的距离,其作用是判断i是否大于p(如果j<0,则i大于p)
{
if (j < 0 || i + nxt[i - a] >= p) //i大于p(其实j最小只可以到-1,j<0的写法方便读者理解程序),
{ //或者可以继续比较(之所以使用大于等于而不用等于也是为了方便读者理解程序)
if (j < 0)
p = i, j = 0; //如果i大于p
while (p < ls && j < lt && S[p] == T[j])
p++, j++;
extend[i] = j;
a = i;
}
else
extend[i] = nxt[i - a];
}
}
int main(void)
{
int T, i;
scanf("%d", &T);
while (T--)
{
scanf("%s%s", s, t);
int la = strlen(s);
int lb = strlen(t);
reverse(s, s + la);
reverse(t, t + lb);
getnxt(t, lb, nxt);
getextend(s, t, la, lb, ex, nxt);
LL ans = 0;
for (i = 0; i < la; ++i)
{
LL temp = (LL)ex[i] * ((LL)ex[i] + 1LL) / 2LL;
ans = (ans + temp) % mod;
}
printf("%I64d\n", ans);
}
return 0;
}
HDU 6153 A Secret(扩展KMP模板题)的更多相关文章
- hdu 1711 Number Sequence(KMP模板题)
我的第一道KMP. 把两个数列分别当成KMP算法中的模式串和目标串,这道题就变成了一个KMP算法模板题. #include<stdio.h> #include<string.h> ...
- HDU 2594 扩展kmp模板题
题目大意: 给定两个字符串,在第一个字符串中找到一个最大前缀作为第二个字符串的后缀 #include <iostream> #include <cstdio> #include ...
- hdu 2087 剪花布条 kmp模板题
也是kuangbin专题的 专题名字太长 不复制了…… 刚好数据结构也学了kmp 找一道题敲敲模板…… 暴力的字符串匹配是O(n*m)的时间复杂度 而kmp通过一个O(m)的预处理将字符串匹配的时间复 ...
- HDU 6153 A Secret(扩展kmp)
A Secret Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Others)Total ...
- A - A Secret -扩展KMP
题目大意: 给你两个字符串A,B,现在要你求B串的后缀在A串中出现的次数和后缀长度的乘积和为多少. 题解: 扩展KMP模板题,将A和B串都逆序以后就变成了求前缀的问题了,扩展KMP求处从i位置开始的最 ...
- HDU 1711 - Number Sequence - [KMP模板题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- kmp模板 && 扩展kmp模板
kmp模板: #include <bits/stdc++.h> #define PB push_back #define MP make_pair using namespace std; ...
- POJ Oulipo KMP 模板题
http://poj.org/problem?id=3461 Oulipo Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4 ...
- POJ Oulipo(KMP模板题)
题意:找出模板在文本串中出现的次数 思路:KMP模板题 #include<cstdio> #include<cstring> #include<cmath> #in ...
随机推荐
- linux下进程的最大线程数、进程最大数、进程打开的文件数
linux下进程的最大线程数.进程最大数.进程打开的文件数 ===========最大线程数============== linux 系统中单个进程的最大线程数有其最大的限制 PTHREAD_TH ...
- python pandas库——pivot使用心得
python pandas库——pivot使用心得 2017年12月14日 17:07:06 阅读数:364 最近在做基于python的数据分析工作,引用第三方数据分析库——pandas(versio ...
- 网站如何使用https
阿里云提供了免费的证书, 先去申请免费的https证书 https://common-buy.aliyun.com/?spm=5176.10695662.958455.3.1f0c7d54HhNTG4 ...
- pyecharts数据分析及展示
仅仅从网上爬下数据当然是不够用的,主要还得对数据进行分析与展示,大部分人都看重薪资,但是薪资数据有的是*k/月,有的是*万/月,还有*万/年等等,就要对数据进行清理 将所有单位统一化,全部换算成统一单 ...
- 2-Linux C语言指针与内存-学习笔记
Linux C语言指针与内存 前面我们对于: c语言的基本用法 makeFile文件的使用 main函数的详解 标准输入输出流以及错误流管道 工具与原理 指针与内存都是c语言中的要点与难点 指针 数组 ...
- C++ 求阶乘
#include<iostream> using namespace std; ; //输入阶乘数 int main() { long long factorial[size]; fact ...
- node获取URL数据
req.method -->GET req.hostname -->127.0.0.1 req.originalUrl -->/test/test/test?name=wang ...
- P1196 银河英雄传说(加权并查集)
P1196 银河英雄传说 题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在 ...
- LeetCode:17. Letter Combinations of a Phone Number(Medium)
1. 原题链接 https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/ 2. 题目要求 给定一 ...
- Jexus支持HTTPS协议
众所周知,在HTTPS页面请求HTTP资料的时候,现代浏览器会拦截,提示用户是否继续,或者直接拦截,提示都不出来. 最近给自己做了个快速书签工具,点击书签就直接把书签发送到服务器地址,然后保存到我的网 ...