[P2408] Luo valley number of distinct sub-strings (suffix automaton)

Topic Link
naked body is.
Build a \ (the SAM \) , \ (the DAG \) run on \ (the DP \) , \ (F [U] =. 1 + \ SUM _ {(U, V) \ in the DAG} F [V] \)
answers \ (F [. 1] -1 \) (since there is no root character)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1000010;
struct SAM{
    int ch[26];
    int len, fa;
}sam[MAXN << 1];
int las = 1, cnt = 1;
long long f[MAXN << 1];
inline void add(int c){
    int p = las; int np = las = ++cnt;
    sam[np].len = sam[p].len + 1;
    for(; p && !sam[p].ch[c]; p = sam[p].fa) sam[p].ch[c] = np;
    if(!p) sam[np].fa = 1;
    else{
        int q = sam[p].ch[c];
        if(sam[q].len == sam[p].len + 1) sam[np].fa = q;
        else{
            int nq = ++cnt; sam[nq] = sam[q];
            sam[nq].len = sam[p].len + 1;
            sam[q].fa = sam[np].fa = nq;
            for(; p && sam[p].ch[c] == q; p = sam[p].fa) sam[p].ch[c] = nq;
        }
    }
}
char a[MAXN];
long long ans;
void dfs(int u){
    f[u] = 1;
    for(int i = 0; i < 26; ++i)
        if(sam[u].ch[i]){
            if(!f[sam[u].ch[i]])
                dfs(sam[u].ch[i]);
            f[u] += f[sam[u].ch[i]];
        }
}
int len;
int main(){
    scanf("%d", &len);
    scanf("%s", a + 1);
    for(int i = 1; i <= len; ++i)
       add(a[i] - 'a');
    dfs(1);
    printf("%lld\n", f[1] - 1);
    return 0;
}

Guess you like

Origin www.cnblogs.com/Qihoo360/p/10986643.html