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 }

时间: 2024-08-24 10:39:54

uvalive 4513 Stammering Aliens的相关文章

UVALive - 4513 Stammering Aliens ——(hash+二分 || 后缀数组加二分)

题意:找一个出现了m次的最长子串,以及这时的最右的位置. hash的话代码还是比较好写的,,但是时间比SA多很多.. 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 using namespace std; 5 const int N = 40000 + 100; 6 typedef long long ll; 7 const int X = 257; 8 const int mod

LA 4513 Stammering Aliens 字符串hash

字符串hash模板, 本题是求,给定字符串s中至少出现m次的最长字符串长度,及此时起始位置的最大值 LA 4513  Stammering Aliens 白书p225 //#pragma warning (disable: 4786) //#pragma comment (linker, "/STACK:16777216") //HEAD #include <cstdio> #include <ctime> #include <cstdlib> #i

字符串hash LA 4513 Stammering Aliens

题目传送门 题意:训练之南P225 分析:二分寻找长度,用hash值来比较长度为L的字串是否相等. #include <bits/stdc++.h> using namespace std; typedef unsigned long long ull; const int N = 4e4 + 5; const int x = 123; ull H[N], _hash[N], xp[N]; int rk[N]; char str[N]; int m; void get_hash(char *s

uva 12206 - Stammering Aliens(哈希)

题目链接:uva 12206 - Stammering Aliens 题目大意:给出一个字符串,找出至少出现m次的最长子串. 解题思路:哈希算法,将每个后缀数组建立一个哈希值,每次二分长度判断,每次判断时将哈希值排序,计数即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef unsigned long long ll; const int ma

UVA 12206 - Stammering Aliens(后缀数组)

UVA 12206 - Stammering Aliens 题目链接 题意:给定一个序列,求出出现次数大于m,长度最长的子串的最大下标 思路:后缀数组,搞出height数组后,利用二分去查找即可 这题之前还写过hash的写法也能过,不过写后缀数组的时候,犯了一个傻逼错误,把none输出成node还一直找不到...这是刷题来第二次碰到这种逗比错误了,还是得注意.. 代码: #include <cstdio> #include <cstring> #include <algori

POJ 3882 Stammering Aliens 后缀数组height应用

题目来源:POJ 3882 Stammering Aliens 题意:给你m一个一个字符串 求至少出现m次的最长字符串 可以在字符串中重叠出现 思路:二分长度l 然后从height数组中找长度大于等于l的前缀 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 40010; char s[maxn]; int sa[maxn]; i

Stammering Aliens

Time Limit: 2000MS   Memory Limit: 65536K       Description Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all efforts to decode their messages have failed so far because, as luck would have it, they have st

poj 3882(Stammering Aliens) 后缀数组 或者 hash

后缀数组:  构建后缀数组,注意要在字符串莫末尾加上一个没出现过的字符.然后可以2分或者直接扫描,直接扫描需要用单调队列来维护 VIEW CODE #include<cstdio> #include<algorithm> #include<iostream> #include<cmath> #include<queue> #include<stack> #include<string> #include<cstrin

UVALive4513 Stammering Aliens(哈希法 | 后缀数组)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=12580 [思路] 求出现次数不小于k次的最长可重复子串和最后的出现位置. 法一: 后缀数组,二分长度,划分height.时间复杂度为O(nlogn) 法二: Hash法.构造字符串的hash函数,二分长度,求出hash(i,L)后排序,判断是否存在超过k个相同hash 值得块即可.时间为O(nlog2n). 注意划分height一定要精确且如果m=1需要特判(对于