NEU 1351 Goagain and xiaodao's romantic story I

题目描述

Do you know goagain? If the answer is no, well, you can leave NEUACM. Goagain is the most perfect ACMer in NEUACM, and his teams name is NEU_First Final. Besides this, goagain is also a Gao-Fu-Shuai. One day he falls in love a Bai-Fu-Mei, named xiaodao, another perfect ACMer in HIT. Though they only come across once, goagain has xiaodao daily and nightly in his thought. Finally goagain decides to express his love to xiaodao.After a long time, xiaodao replys to goagain that he needs to experience a test.

There is a string S =[ s1,s2,s3,s4,s5,......sn ], and then m queries. Goagain s task is to calculate the longest prefix between suffix(a) and suffix(b) (1<=a,b<=L(s),a!=b)

For example , string  A=[ a1,a2,a3,a4,.....an ].

Suffix(i)= [ ai,ai+1,ai+2,ai+3,.....an ].

Prefix of a string is [ a1,a2,a3,a4.....aj ] j<=n

输入

There are several cases. For each case , the first line is string s(1<=L(s)<=100000).

输出

For each case, output the length of the longest prefix .

aabaaaab

样例输出

3

sl: 很显然的做法是后缀数组。。。本菜鸟不会，只好拿字符串hash恶搞。

满足hash函数 hash[i][L]=H[i]-H[i+L]*xp[L];

H[i]=H[i+1]*x+s[i]-'a';

x为一个素数。

1 #include<cstdio>

2 #include<cstring>
3 #include<algorithm>
4  using  namespace std;
5  const  int MAX =  100000+ 10;
6 typedef unsigned  long  long LL;
7  const  int x=  123;
8 LL H[MAX],xp[MAX];
9  int id[MAX];
10 LL hash[MAX];
11  int n;  char str[MAX];
12
13  int cmp( int a, int b)
14 {
15      if(hash[a]!=hash[b])  return hash[a]<hash[b];
16      else  return a<b;
17 }
18
19  int check( int L)
20 {
21      int cnt= 0;
22      for( int i= 0;i<n-L+ 1;i++)
23     {
24         id[i]=i;
25         hash[i]=H[i]-H[i+L]*xp[L];
26     }
27     sort(id,id+n-L+ 1,cmp);
28      for( int i= 0;i<n-L+ 1;i++)
29     {
30          if(i== 0||hash[id[i]]!=hash[id[i- 1]]) cnt= 0;
31          if(++cnt>= 2) return  1;
32     }
33      return  0;
34 }
35
36  int main()
37 {
38      // freopen("1.txt","r",stdin);
39       while(scanf( " %s ",str)== 1)
40     {
41         n=strlen(str);
42         H[n]= 0;
43          for( int i=n- 1;i>= 0;i--) H[i]=H[i+ 1]*x+str[i]- ' a ';
44         xp[ 0]= 1;
45          for( int i= 1;i<=n;i++) xp[i]=xp[i- 1]*x;
46          if(!check( 1)) printf( " 0\n ");
47          else
48         {
49              int L= 1,R=n+ 1int ans;
50              while(L<=R)
51             {
52                  int mid=(R+L)>> 1;
53                  if(check(mid)) ans=mid,L=mid+ 1;
54                  else R=mid- 1;
55             }
56             printf( " %d\n ",ans);
57         }
58     }
59     return 0

11-09
09-26  10-01
08-26
07-25
06-20 1241
02-20
12-27
03-20 点击重新获取   扫码支付  余额充值