uvalive 4513 Stammering Aliens

题意:给你一个串,问期中至少出现m次的最长子串及其起始位置的坐标。

思路:hash+LCP+二分答案

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int maxn = 40000 + 10;
 7 const int x = 123;
 8 int n, m, pos;
 9 unsigned long long H[maxn], xp[maxn];
10 
11 unsigned long long hash[maxn];
12 int rank[maxn];
13 
14 int cmp(const int& a, const int& b)
15 {
16     return hash[a] < hash[b] || (hash[a] == hash[b] && a < b);
17 }
18 
19 int possible(int L)
20 {
21     int c = 0;
22     pos = -1;
23     for(int i = 0; i < n-L+1; i++)
24     {
25         rank[i] = i;
26         hash[i] = H[i] - H[i+L]*xp[L];
27     }
28     sort(rank, rank+n-L+1, cmp);
29     for(int i = 0; i < n-L+1; i++)
30     {
31         if(i == 0 || hash[rank[i]] != hash[rank[i-1]])
32             c = 0;
33         if(++c >= m)
34             pos = max(pos, rank[i]);
35     }
36     return pos >= 0;
37 }
38 
39 int main()
40 {
41     char s[maxn];
42     while(scanf("%d", &m) == 1 && m)
43     {
44         scanf("%s", s);
45         n = strlen(s);
46         H[n] = 0;
47         for(int i = n-1; i >= 0; i--)
48             H[i] = H[i+1]*x + (s[i] - 'a');
49         xp[0] = 1;
50         for(int i = 1; i <= n; i++)
51             xp[i] = xp[i-1]*x;
52         if(!possible(1))
53             printf("none\n");
54         else
55         {
56             int L = 1, R = n+1;
57             while(R - L > 1)
58             {
59                 int M = L + (R-L)/2;
60                 if(possible(M))
61                     L = M;
62                 else R = M;
63             }
64             possible(L);
65             printf("%d %d\n", L, pos);
66         }
67     }
68     return 0;
69 }
View Code

 

posted @ 2015-12-20 20:34  yyblues  阅读(191)  评论(0编辑  收藏  举报