無名(noname)

【问题描述】

因为是蒯的题所以没想好名字,为什么要用繁体呢?去看《唐诗三百首》吧!

题意很简单,给你一个串,求他有多少个不同的子串,满足前缀为A,后缀为B。

需要注意的是,串中所有的字母都是小写字母。

友情提示:如果你过不了样例,请注意是不同的子串。                    

【输入文件】

一共3行。

第一行母串S;

第二行串A;

第三行串B。

【输出文件】

    一个数,即有多少不同的子串。

【输入样例】

abababab

a

b

 

【输出样例】

4

 

【数据规模和约定】

100%:

length(S)<=2000;

length(A)<=2000;

length(B)<=2000;

30%:都少个0

字符串hash

首先,枚举每一个后缀是否前缀为A,front[i]表示i~l-1的前缀是否为A

同理处理出bside[i]表示0~i的后缀是否为B

枚举左右端点,可知当2个数组都为1才为一个解

但是解不能重复

于是用字符串hash,就是将字符串转数

hash[i]表示0~i的hash值

hash[i]=((hash[i-1]*p+idx(s[i]))%Mod

Mod和p都要慎重考虑,p取31,Mod取1e7+7

那么l~r的hash值为:hash(l~r)=(hash[r]-hash[l-1]*p^(r-l+1)+Mod)%Mod

一般Mod取1e9+7,但是这里要用bool数组,所以取1e7+7

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int p=31,Mod=100000007;
 7 int l,la,lb,front[2001],bside[2001];
 8 char s[2001],A[2001],B[2001];
 9 long long pow[2001],hash[2001],ans;
10 bool vis[100000007];
11 bool ask(int x,int y)
12 {
13     long long h=(hash[y]-(hash[x-1]*pow[y-x+1]%Mod)+Mod)%Mod;
14     if (vis[h]==0)
15     {
16      vis[h]=1;
17      return 1;
18     }
19     else 
20     {
21      return 0;
22     }
23 }
24 int main()
25 {int i,j;
26 //freopen("noname.in","r",stdin);
27 //freopen("noname.out","w",stdout);
28     cin>>s;
29     cin>>A;
30     cin>>B;
31     l=strlen(s);
32     la=strlen(A);
33     lb=strlen(B);
34      for (i=0;i<l;i++)
35      {
36         for (j=1;j<=la,j+i-1<l;j++)
37          if (A[j-1]!=s[i+j-1]) break;
38         if (j>la)
39          front[i]=1;
40      }
41      for (i=l-1;i>=0;i--)
42      {
43         for (j=1;j<=lb,i-j+1>=0;j++)
44         if (B[lb-j]!=s[i-j+1]) break;
45         if (j>lb)
46          bside[i]=1;
47      }
48      hash[1]=(int)s[0]-96;
49     for (i=2;i<=l;i++)
50     {
51       hash[i]=(hash[i-1]*p+(int)s[i-1]-96)%Mod;
52     }
53     pow[0]=1;
54      for (i=1;i<=l;i++)
55       pow[i]=(pow[i-1]*p)%Mod;
56     for (i=0;i<l;i++)
57     {
58      for (j=i+max(la,lb)-1;j<l;j++)
59      if (front[i]&&bside[j])
60        if (ask(i+1,j+1)) ans++;
61     }
62 cout<<ans;
63 }

 

posted @ 2017-08-23 16:42  Z-Y-Y-S  阅读(312)  评论(0编辑  收藏  举报