1003:hint有修改,已加粗。请各位选手注意。More...
Another Meaning
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1508 Accepted Submission(s): 382
Problem Description
As is known to all, in many cases, a word has two meanings. Such as “hehe”, which not only means “hehe”, but also means “excuse me”.
Today, ?? is chating with MeiZi online, MeiZi sends a sentence A to ??. ?? is so smart that he knows the word B in the sentence has two meanings. He wants to know how many kinds of meanings MeiZi can express.
Input
The first line of the input gives the number of test cases T; T test cases follow.
Each test case contains two strings A and B, A means the sentence MeiZi sends to ??, B means the word B which has two menaings. string only contains lowercase letters.
Limits
T <= 30
|A| <= 100000
|B| <= |A|
Output
For each test case, output one line containing “Case #x: y” (without quotes) , where x is the test case number (starting from 1) and y is the number of the different meaning of this sentence may be. Since this number may be quite large, you should output the answer modulo 1000000007.
Sample Input
4 hehehe hehe woquxizaolehehe woquxizaole hehehehe hehe owoadiuhzgneninougur iehiehieh
Sample Output
Case #1: 3 Case #2: 2 Case #3: 5 Case #4: 1
Hint
In the first case, “ hehehe” can have 3 meaings: “*he”, “he*”, “hehehe”. In the third case, “hehehehe” can have 5 meaings: “*hehe”, “he*he”, “hehe*”, “**”, “hehehehe”.
【题意】给你两个字符串,用b串匹配a串,在两个串完全匹配的位置,可以通过变换变成一个*,a串上可以多个位置都变换,问最后a串有多少种形式。
【分析】我们可以通过扩展kmp,extend[i]:y[i..n-1]与x[0...m-1]的最长公共前缀,判断是否完全匹配。
然后dp,状态表示: dp[i]代表以i为结尾的a串有多少表现形式。
状态转移: (1)当以i为结尾的a的字串与b完全匹配时,dp[i]=dp[i]-lenb+dp[i-1];
(2) 没有完全匹配时,dp[i]=dp[i-1];
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#define F first
#define S second
#define mp make_pair
using namespace std;
const int maxn = 1e5+10;
const int mod = 1000000007;
char a[maxn];
char b[maxn];
int nextt[maxn];
int extend[maxn];
int dp[maxn];
void pre_EKMP(char x[],int m,int next[])
{
next[0]=m;
int j=0;
while(j+1<m && x[j]==x[j+1]) j++;
next[1]=j;
int k=1;
for(int i=2; i<m; i++)
{
int p=next[k]+k-1;
int L=next[i-k];
if(i+L<p+1) next[i]=L;
else
{
j=max(0,p-i+1);
while(i+j<m && x[i+j]==x[j])j++;
next[i]=j;
k=i;
}
}
}
void EKMP(char x[],int m,char y[],int n,int next[],int extend[])
{
pre_EKMP(x,m,next);
int j=0;
while(j<n && j<m && x[j]==y[j])j++;
extend[0]=j;
int k=0;
for(int i=1; i<n; i++)
{
int p=extend[k]+k-1;
int L=next[i-k];
if(i+L<p+1) extend[i]=L;
else
{
j=max(0,p-i+1);
while(i+j<n && j<m && y[i+j]==x[j])j++;
extend[i]=j;
k=i;
}
}
}
int main()
{
int T;
scanf("%d",&T);
int u=1;
while(T--)
{
scanf("%s",a);
scanf("%s",b);
EKMP(b,strlen(b),a,strlen(a),nextt,extend);
int lena=strlen(a);
int lenb=strlen(b);
memset(dp,0,sizeof(dp));
for(int i=0; i<lenb-1; i++) dp[i]=1;
for(int i=lenb-1; i<lena; i++)
{
if(extend[i-lenb+1]==lenb)
{
if(i-lenb<0) dp[i]++;
else
dp[i]+=dp[i-lenb];
dp[i]%=mod;
if(i-1<0) dp[i]++;
else
dp[i]+=dp[i-1];
dp[i]%=mod;
}
else
{
dp[i]+=dp[i-1];
dp[i]%=mod;
}
}
printf("Case #%d: %d\n",u++,dp[lena-1]);
}
return 0;
}