zoukankan      html  css  js  c++  java
  • A Secret(KMP)

    A Secret

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


    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中国大学生程序设计竞赛 - 网络选拔赛

     

    //题意,一个S串,一个T串,问T的每一个后缀串在S串的匹配次数乘后缀串长度之和为多少。

    //题解:S,T串逆序后,跑一遍kmp,并且统计匹配度的次数,然后,从lent向前推,因为在匹配时,没有累计T串中T串自己的可匹配情况,

    例如逆序后, S: aba T: aba

    kmp后,num : 1 1 1 (长为1的匹配数,长为2的匹配数,长为3的匹配数)

    而实际,num: 2 1 1 ,因为 aba 匹配成功后,还包含了一次 a 的匹配

    所以,最后还要逆序跑一下,利用fail(next)数组来加上,即为答案

     1 # include <cstdio>
     2 # include <cstring>
     3 # include <cstdlib>
     4 # include <iostream>
     5 # include <vector>
     6 # include <queue>
     7 # include <stack>
     8 # include <map>
     9 # include <bitset>
    10 # include <sstream>
    11 # include <set>
    12 # include <cmath>
    13 # include <algorithm>
    14 # pragma  comment(linker,"/STACK:102400000,102400000")
    15 using namespace std;
    16 # define LL          long long
    17 # define pr          pair
    18 # define mkp         make_pair
    19 # define lowbit(x)   ((x)&(-x))
    20 # define PI          acos(-1.0)
    21 # define INF         0x3f3f3f3f3f3f3f3f
    22 # define eps         1e-8
    23 # define MOD         1000000007
    24 
    25 inline int scan() {
    26     int x=0,f=1; char ch=getchar();
    27     while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    28     while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    29     return x*f;
    30 }
    31 inline void Out(int a) {
    32     if(a<0) {putchar('-'); a=-a;}
    33     if(a>=10) Out(a/10);
    34     putchar(a%10+'0');
    35 }
    36 #define MX 1000050
    37 /**************************/
    38 int lens,lent;
    39 char S[MX];
    40 char T[MX];
    41 int num[MX];
    42 int fail[MX];
    43 
    44 void get_next(char * t)
    45 {
    46     int i=0,j=-1;
    47     fail[0]=-1;
    48     while(i<lent)
    49     {
    50         if (j==-1||T[i]==T[j])
    51             fail[++i]=++j;
    52         else
    53             j=fail[j];  //回溯
    54     }
    55 }
    56 
    57 void KMP(char *s,char *t)
    58 {
    59     memset(num,0,sizeof(num));
    60     get_next(t);
    61     int i=0,j=0;
    62     while (i<lens)
    63     {
    64         if (j==-1||S[i]==T[j])
    65         {
    66             i++,j++;
    67         }
    68         else j = fail[j];
    69 
    70         if (j!=-1) num[j]++;
    71 
    72         if (j==lent) j = fail[j];
    73     }
    74 }
    75 
    76 int main()
    77 {
    78     int cas = scan();
    79     while (cas--)
    80     {
    81         scanf("%s",S);
    82         scanf("%s",T);
    83         lens = strlen(S);
    84         lent = strlen(T);
    85         reverse(S,S+lens);
    86         reverse(T,T+lent);
    87         KMP(S,T);
    88         LL ans = 0;
    89         for (int i=lent;i>0;i--)
    90         {
    91             num[fail[i]]+=num[i];
    92             ans = (ans + ((LL)i*num[i])%MOD)%MOD;
    93         }
    94         printf("%lld
    ",ans);
    95     }
    96     return 0;
    97 }
    View Code
  • 相关阅读:
    文件隐藏在一张图片里
    晶振
    主宰全球的10大算法
    java+mysql连接的优化
    排序剔除
    js数据类型
    字符实体
    表单
    定义样式表
    布局相关的属性
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/7399298.html
Copyright © 2011-2022 走看看