2016暑假多校联合---Another Meaning

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”.
 
思路:递推(DP) 当前位置以前的语句的含义种数为包含当前多语义与不包含;
 
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const long long mod=1e9+7;

char s[100005];
char ss[100005];
int next1[100005];
long long num[100005];
int       pos[100005];

void makenext1(const char P[])
{
    int q,k;
    int m = strlen(P);
    next1[0]=0;
    for (q = 1,k = 0; q < m; ++q)
    {
        while(k > 0 && P[q] != P[k])
            k = next1[k-1];
        if (P[q] == P[k])
        {
            k++;
        }
        next1[q] = k;
    }
}

long long calc(char T[],char P[])
{
    int n,m;
    int i,q;
    int tot=0;
    n = strlen(T);
    m = strlen(P);
    makenext1(P);
    for(i=0,q = 0; i < n; ++i)
    {
        while(q>0&&P[q]!=T[i])
            q=next1[q-1];
        if(P[q]==T[i])
        {
            q++;
        }
        if(q==m)
        {
            long long flag=1;
            pos[tot]=i-m+1;
            if(tot>0)
            {
                if(pos[tot-1]+m<=pos[tot])
                {
                    num[tot]=(2*num[tot-1])%mod;
                }
                else
                {
                    num[tot]=num[tot-1]%mod;
                    for(int h=tot-2;h>=0;h--)
                   {
                       if(pos[h]+m<=pos[tot])
                      {
                         num[tot]=(num[tot]+num[h])%mod;
                         flag=0;  ///当之前不存在不相重叠的语句时;
                         break;
                      }
                   }
                   num[tot]=(num[tot]+flag)%mod;
                }
            }
            else
            {
                num[tot]=2;
            }
            tot++;
         }
    }
    if(tot==0) return 1;
    return num[tot-1];
}

int main()
{
    int T;
    int Case=1;
    cin>>T;
    while(T--)
    {
        scanf("%s%s",s,ss);
        printf("Case #%d: %lld\n",Case++,calc(s,ss));
       // cout<<(calc(s,ss)%mod+mod)%mod<<endl;
    }
    return 0;
}

 

posted @ 2016-08-02 12:00  茶飘香~  阅读(309)  评论(0编辑  收藏  举报