CF235C Cyclical Quest

meaning of the title

Given a parent string \(q\) group of length \(n\) , ask this string to be rotated (that is, drop the last digit to the front), ask this string and its rotated string to be in the given string How many times does it appear in


Sol

Rotate, copy it and connect it to the back,
then match it on \(sam\)
, jump to the father of the \(parent\) tree to the last one whose length is greater than or equal to the length of the query string,
and then count \(size\)
to prevent repeated calculations, just mark Check this point

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
 
IL int Input(){
    RG int x = 0, z = 1; RG char c = getchar();
    for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x * z;
}

const int maxn(2e6 + 5);

int len[maxn], trans[26][maxn], fa[maxn], tot = 1, last = 1;
int n, q, id[maxn], t[maxn], size[maxn], vis[maxn];
char s[maxn];

IL void Extend(RG int c){
    RG int p = last, np = ++tot;
    len[last = np] = len[p] + 1, size[np] = 1;
    while(p && !trans[c][p]) trans[c][p] = np, p = fa[p];
    if(!p) fa[np] = 1;
    else{
        RG int q = trans[c][p];
        if(len[q] == len[p] + 1) fa[np] = q;
        else{
            RG int nq = ++tot;
            fa[nq] = fa[q], len[nq] = len[p] + 1;
            for(RG int i = 0; i < 26; ++i) trans[i][nq] = trans[i][q];
            fa[np] = fa[q] = nq;
            while(p && trans[c][p] == q) trans[c][p] = nq, p = fa[p];
        }
    }
}

int main(){
    scanf(" %s", s), n = strlen(s);
    for(RG int i = 0; i < n; ++i) Extend(s[i] - 'a');
    for(RG int i = 1; i <= tot; ++i) ++t[len[i]];
    for(RG int i = 1; i <= tot; ++i) t[i] += t[i - 1];
    for(RG int i = 1; i <= tot; ++i) id[t[len[i]]--] = i;
    for(RG int i = tot; i; --i) size[fa[id[i]]] += size[id[i]];
    q = Input();
    for(RG int i = 1, l, tl; i <= q; ++i){
        scanf(" %s", s + 1), l = strlen(s + 1);
        for(RG int j = 1; j < l; ++j) s[j + l] = s[j];
        RG ll ans = 0; tl = l + l;
        for(RG int j = 1, nw = 1, cnt = 0; j < tl; ++j){
            while(nw && !trans[s[j] - 'a'][nw]) nw = fa[nw], cnt = len[nw];
            if(!nw) nw = 1, cnt = 0;
            else ++cnt, nw = trans[s[j] - 'a'][nw];
            while(nw && len[fa[nw]] >= l) nw = fa[nw], cnt = len[nw];
            if(cnt >= l && vis[nw] != i) ans += size[nw], vis[nw] = i;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324854680&siteId=291194637