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>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FD(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define CPY(a, b) memcpy(a, b, sizeof(a))
#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RS(s) scanf("%s", s)
//OUTPUT
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s)

const int INF = 0x3f3f3f3f;

#define ULL unsigned long long

const int maxn = 40010;
const int SEED = 13331;
int n, m;
int rank[maxn];
char s[maxn];

ULL xp[maxn];
ULL hashs[maxn];
int pos;

ULL ha[maxn];
int cmp(const int &a, const int &b)///cmp注意
{
    return ha[a] < ha[b] || (ha[a] == ha[b] && a < b);
}
int possible(int L)
{
    for (int i = 0; i < n - L + 1; i++)
    {
        rank[i] = i;
        ///
        ha[i] = hashs[i] - hashs[i + L] * xp[L];
    }
    sort(rank, rank + n - L + 1, cmp);
    int x;
    pos = -1;
    for (int i = 0; i < n - L + 1; i++)
    {
        if (i == 0 || ha[rank[i]] != ha[rank[i - 1]]) x = 0;
        if (++x >= m) pos = max(pos, rank[i]);
    }
    return pos >= 0;
}

int main()
{
    ///
    xp[0] = 1;
    for (int i = 1; i < maxn; i++)
        xp[i] = xp[i - 1] * SEED;

    while (cin >> m && m)
    {
        RS(s);
        n = strlen(s);

        ///
        hashs[n] = 0;
        for (int i = n - 1; i >= 0; i--)
            hashs[i] = hashs[i + 1] * SEED + s[i];

        if (!possible(1)) puts("none");
        else
        {
            int L = 1, R = n;
            while (L <= R)
            {
                int M = (L + R) >> 1;
                if (possible(M)) L = M + 1;
                else R = M - 1;
            }
            possible(R);
            printf("%d %d\n", R, pos);
        }

    }
    return 0;
}

LA 4513 Stammering Aliens 字符串hash

时间: 2024-11-11 04:58:38

LA 4513 Stammering Aliens 字符串hash的相关文章

字符串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

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

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], x

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

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

UVa 12206 (字符串哈希) Stammering Aliens

体验了一把字符串Hash的做法,感觉Hash这种人品算法好神奇. 也许这道题的正解是后缀数组,但Hash做法的优势就是编码复杂度大大降低. 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 unsigne

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

HDU 4821 字符串hash

题目大意: 希望找到连续的长为m*l的子串,使得m个l长的子串每一个都不一样,问能找到多少个这样的子串 简单的字符串hash,提前预处理出每一个长度为l的字符串的hash值 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <map> 6 #include <set> 7 8 using na

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