码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 6153

时间:2017-08-29 12:53:20      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:它的   tle   mem   ons   blog   trre   next   http   memset   

http://acm.hdu.edu.cn/showproblem.php?pid=6153

题意:有两个字符串,第一个是母串,第二个是子串,问子串的前缀可以匹配多少个母串,然后在乘以它的长度的总和

思路:把字符串反过来,用kmp匹配,然后匹配的时候统一一下这个串出现过多少次,然后还有就是这个串的子串出现的次数一定要加上它

因为如果可以匹配后面的,那么前面的也是一定可以匹配的。那么也就是前面的也是它的子串

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 const int mod = 1e9+7;
 4 const int maxn = 1e6+50;
 5 char s[maxn];
 6 char t[maxn];
 7 int next[maxn];
 8 long long cnt[maxn];
 9 
10 void getnext()
11 {
12     int i = 0 , j = -1;
13     next[0] = -1;
14     int len = strlen(t);
15     while(i<len)
16     {
17         if(j==-1||t[i]==t[j])
18             next[++i] = ++j;
19         else
20             j = next[j];
21     }
22 }
23 
24 void kmp_count()
25 {
26     int slen = strlen(s);
27     int tlen = strlen(t);
28     getnext();
29     long long ans = 0;
30     for(int i = 0,j = 0;i<=slen;i++)
31     {
32         while(j&&s[i]!=t[j])
33         {
34             cnt[j]++;
35             j = next[j];
36         }
37         if(s[i]==t[j])
38             j++;
39         if(j==tlen)
40         {
41             cnt[j]++;
42             j = next[j];
43         }
44     }
45     for(int i = tlen;i>=0;i--)
46     {
47         cnt[i] += cnt[i+1];
48         ans =(ans%mod+((cnt[i]%mod)*i)%mod)%mod;
49     }
50     printf("%lld\n",ans);
51 }
52 
53 
54 int main()
55 {
56     int tt;
57     scanf("%d",&tt);
58     while(tt--)
59     {
60         memset(s,0,sizeof(s));
61         memset(t,0,sizeof(t));
62         memset(cnt,0,sizeof(cnt));
63         scanf("%s%s",s,t);
64         strrev(s);
65         strrev(t);
66         kmp_count();
67     }
68     return 0;
69 }

 

hdu 6153

标签:它的   tle   mem   ons   blog   trre   next   http   memset   

原文地址:http://www.cnblogs.com/Tree-dream/p/7447158.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!