HDU6513/CCPC2017--A Secret(KMP)

A Secret

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Others)
Total Submission(s): 461    Accepted Submission(s): 182

Problem Description

Today is the birthday of SF,so VS gives two strings S1,S2 to SF as a present,which have a big secret.SF is interested in this secret and ask VS how to get it.There are the things that VS tell:
  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.

Input

Input contains multiple cases.
  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.

Output

For each test case,output a single line containing a integer,the answer of test case.
  The answer may be very large, so the answer should mod 1e9+7.

Sample Input


2
aaaaa
aa
abababab
aba

Sample Output


13
19

Hint

case 2:
Suffix(S2,1) = "aba",
Suffix(S2,2) = "ba",
Suffix(S2,3) = "a".
N1 = 3,
N2 = 3,
N3 = 4.
L1 = 3,
L2 = 2,
L3 = 1.
ans = (3*3+3*2+4*1)%1000000007.
 

Source

2017中国大学生程序设计竞赛 - 网络选拔赛

题意:

给出两个字符串S1,S2,求S2的所有后缀在S1中匹配到的次数与其后缀长度的乘积之和

思路:

由于乘上了后缀长度,所以对某个后缀的匹配而言,每个字母对答案的贡献是1

由此,我们可以将字符串反转,然后跑一遍kmp,在kmp的过程中统计有多少匹配,并加上他们的贡献即可

代码:

  1 /*
  2 * @FileName: D:\代码与算法\2017训练比赛\CCPC网络赛\1004-bt.cpp
  3 * @Author: Pic
  4 * @Date:   2017-08-19 16:30:09
  5 * @Last Modified time: 2017-08-19 20:54:48
  6 */
  7 #include <bits/stdc++.h>
  8 using namespace std;
  9 /*
 10 * next[]的含义: x[i-next[i]...i-1]=x[0...next[i]-1]
 11 * next[i]为满足x[i-z...i-1]=x[0...z-1]的最大z值(就是x的自身匹配)
 12 */
 13 long long sum=0;
 14 const long long mod=1e9+7;
 15 const long long MAXN=2e6+30;
 16 char x[MAXN],y[MAXN];
 17 int nxt[MAXN];
 18 void kmp_pre(char x[],int m)
 19 {
 20     long long i, j;
 21     j = nxt[0] = -1;
 22     i = 0;
 23     while (i < m)
 24     {
 25         while (-1 != j && x[i] != x[j])j = nxt[j];
 26         nxt[++i] = ++j;
 27     }
 28 }
 29 /*
 30 * kmpNext[]的意思: next‘[i]=next[next[...[next[i]]]] (直到next‘[i]<0或者
 31 x[next‘[i]]!=x[i])
 32 * 这样的预处理可以快一些
 33 */
 34 void KMP_Count( char x[],int m,  char y[],int n)
 35 {    //x是模式串, y是主串
 36     long long i, j;
 37     kmp_pre(x,m);
 38     i = j = 0;
 39     while (i < n)
 40     {
 41         while (-1 != j && y[i] != x[j]) {
 42             sum = (sum+((1+j)*j/2)%mod)%mod;
 43             j = nxt[j];
 44         }
 45         i++; j++;
 46         //sum=(sum+j)%mod;
 47         if (j >= m)
 48         {
 49             sum = (sum+((1+j)*j/2)%mod)%mod;
 50             j = nxt[j];
 51         }
 52     }
 53     while(j>=1){
 54     	sum = (sum+((1+j)*j/2)%mod)%mod;
 55     	j=nxt[j];
 56     }
 57 }
 58 int main()
 59 {
 60    // clock_t startTime,endTime;
 61     //startTime = clock();
 62     //freopen("data.in","r",stdin);
 63     //freopen("out.txt","w",stdout);
 64     int t;
 65     scanf("%d",&t);
 66     while(t--){
 67         scanf("%s%s",y,x);
 68         int len1=strlen(y);
 69         int len2=strlen(x);
 70         reverse(x,x+len2);
 71         reverse(y,y+len1);
 72         sum=0;
 73         KMP_Count(x,len2,y,len1);
 74         printf("%I64d\n",sum);
 75     }
 76     //endTime = clock();
 77     //cout << "Totle Time : " <<(double)(endTime - startTime)<< "ms" << endl;
 78     return 0;
 79 }

时间: 2024-12-11 10:10:30

HDU6513/CCPC2017--A Secret(KMP)的相关文章

HDU3336-Count the string(KMP)

Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4449    Accepted Submission(s): 2094 Problem Description It is well known that AekdyCoin is good at string problems as well as n

CQU 单词替换(KMP)

单词替换(KMP) Time Limit: 500 MS Memory Limit: 64000 K Description 给出一个仅包含小写字母的字符串s,和单词A,B.把s中所有的出现过的A替换为B. Input 第一行一个数T(1<=T<=10),表示数据组数 每组数据三行,第一行为s,第二行为A,第三行为B.所有字符串仅包含小写字母 且长度小于5,000,000. Output 每组数据输出一行,替换后的字符串. Sample Input 3 aaa a b aaa aa b aba

串的模式匹配算法(KMP)

算法: #include<IOSTREAM> using namespace std; #define MAXSIZE 100 void calNext(const char *T,int *next);//T为模式串,next为预判数组 int kmp_match(const char *S,const char *T);//在主串S中寻找模式串T,如果找到返回其位置,否则返回-1.位置从0开始 void calNext(const char *T,int *next) { int n =

HDU 2594 Simpsons’ Hidden Talents (KMP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2594 这题直接用KMP算法就可以做出来,不过我还尝试了用扩展的kmp,这题用扩展的KMP效率没那么高. KMP算法: #include<stdio.h> #include<iostream> #include<string.h> using namespace std; int next[50001]; char p[50000],s[50000]; void getnex

hdu 3336 Count the string(KMP)

一道应用kmp算法中next数组的题目 这其中vis[i]从1加到n vis[i]=[next[i]]+1; #include<string.h> #include<stdlib.h> #include<stdio.h> #include<iostream> #include<algorithm> using namespace std; char s[200005]; int b; int next[200005]; int vis[20000

poj1961 &amp; hdu 1358 Period(KMP)

poj 题目链接:http://poj.org/problem?id=1961 hdu题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358 Description For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether

hdu 1686 Oulipo (kmp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1686 题目大意:寻找子链在母链中出现的次数. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int next[10010],sum,lens,lenc; 6 char str[10010],ch[1000010]; 7 8 int get_nex

codeforces round#259 div2 B题(KMP)

先上链接:http://codeforces.com/contest/454/problem/B B. Little Pony and Sort by Shift time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output One day, Twilight Sparkle is interested in how to sort a se

第四章:2.串 -- 串的模式匹配算法(KMP)

前言: 目录: 1.串类型的定义 2.串的表示和实现 3.串的模式匹配算法 4.串操作应用举例 正文: 串的模式匹配即,在给定主串S 中,搜索子串T 的位置,如果存在T 则返回其所在位置,否则返回 0 串的模式匹配算法 主串 S: a b c a b c d s v t 子串 T: a b c d 一.原始算法 匹配一旦失败,子串即向右移动一个单位,直到完全匹配停止. 第一次匹配:(注:红色代表不匹配(失配)) S: a b c a b c a b c d s v t   T: a b c d