Bzoj3277:3277

topic

portal

Sol

Generalized \(sam
\)The state of each \(sam\) is open \(set\) records belong to which strings
\(parent\) Heuristic merge on the tree \(set\)

Then each string walks on it, by constantly jumping the parent node of the \(parent\) tree to ensure that it is greater than or equal to \(k\) , the contribution is \(len\)

# 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(1e5 + 5);
const int maxm(5e5 + 5);

int trans[26][maxm], fa[maxm], tot = 1, last, len[maxm];
int id[maxm], t[maxm], n, k, size[maxm];
set <int> ed[maxm];
set <int> :: iterator it;
string s[maxn];

IL void Extend(RG int c){
    RG int p = last, np = ++tot;
    len[last = np] = len[p] + 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(RG int argc, RG char *argv[]){
    n = Input(), k = Input();
    for(RG int i = 1; i <= n; ++i){
        cin >> s[i]; last = 1;
        for(RG int j = 0, l = s[i].size(); j < l; ++j) Extend(s[i][j] - 'a');
    }
    for(RG int i = 1; i <= n; ++i)
        for(RG int j = 0, nw = 1, l = s[i].size(); j < l; ++j){
            nw = trans[s[i][j] - 'a'][nw];
            ed[nw].insert(i);
        }
    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){
        RG int x = id[i];
        size[x] = ed[x].size();
        if(size[x] > size[fa[x]]) swap(ed[x], ed[fa[x]]);
        for(it = ed[x].begin(); it != ed[x].end(); ++it)
            ed[fa[x]].insert(*it);
    }
    for(RG int i = 1; i <= n; ++i){
        RG ll ans = 0, nw = 1;
        for(RG int j = 0, l = s[i].size(); j < l; ++j){
            nw = trans[s[i][j] - 'a'][nw];
            while(nw != 1 && size[nw] < k) nw = fa[nw];
            if(size[nw] >= k) ans += len[nw];
        }
        printf("%lld ", ans);
    }
    return 0;
}

Guess you like

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