Loading

CH1807 Necklace (字符串Hash + 最小表示法)

把第一个字符串拼接后就是hash + 最小表示法板子了。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=4000010,P=131;
string s, t, ss;
typedef unsigned long long ULL;
ULL h1[N], p1[N], h2[N], p2[N];
int lens, lent;
ULL get1(int l,int r)
{
    return h1[r] - h1[l-1] * p1[r-l+1];
}
ULL get2(int l,int r)
{
    return h2[r] - h2[l-1] * p2[r-l+1];
}
long long ans = 0;
int main()
{
    //freopen("data.txt", "r", stdin);
    cin >> s;
    cin >> t;
    ss = s;
    s = s + ss;
    lens = s.size(), lent = t.size();
    s = " " + s;
    t = " " + t;
    p1[0] = 1;
    p2[0] = 1;
    for(int i = 1; i <= lens; i++)
    {
        p1[i] = p1[i-1] * P;
        h1[i] = h1[i-1] * P +s[i];
    }
    for(int i = 1;i <= lent; i++)
    {
        p2[i] = p2[i-1] * P;
        h2[i] = h2[i-1] * P +t[i];
    }
    bool flag = 0;
    for(int i = 1; i + lent <= lens; i++)
    {
        if(get1(i, i + lent - 1) == get2(1, lent))
        {
            flag = 1;
            break;
        }
    }
    if(flag) cout << "Yes" << endl;
    else {
        cout << "No" << endl; 
        return 0;
    }


    int i = 1, j = 2, k;
    while(i <= lent && j <= lent) {
        for(k = 0; k < lent && s[i + k] == s[j + k]; k++); 
        if(k == lent) break;
        if(s[i + k] > s[j + k]) {
            i = i + k + 1;
            if(i == j) i++;
        } else {
            j = j + k + 1;
            if(i == j) j++;
        }
    }
    int ans = min(i, j);
    for(int i = ans; i <= ans + lent - 1; i++) {
        cout << s[i];
    }
    return 0;
}
posted @ 2021-03-05 09:16  脂环  阅读(59)  评论(0编辑  收藏  举报