lcp计数 (Trie)

来源:互联网 发布:免费源码分享网站 编辑:程序博客网 时间:2024/05/17 23:23

lcp

思路:
看着挺唬人的,其实是道水题。
考虑每个子串作为lcp的贡献,就是包含这个子串的字符串的两两组合。

#include <cstdio>#include <algorithm>#include <cstring>#include <queue>#include <iostream>#define N 1000005#define LL long longusing namespace std;int n, rot, cnt; int c[N][26], sum[N];char s[N];LL ans;void insert(char *s){    int p = rot, len = strlen(s);    for(int i=0; i<len; i++){        int x = c[p][s[i] - 'a'];        if( !x ) c[p][s[i] - 'a'] = ++cnt;        p = c[p][s[i] - 'a'];        sum[p]++;    }}void query(){    int p = rot;    queue<int> q;    q.push( p );    while( !q.empty() ){        int u = q.front(); q.pop();        for(int i=0; i<26; i++){            int v = c[u][i];            if( !v ) continue;            ans += (1LL * sum[v] * (sum[v] - 1) / 2);            //一共有sum[v]个字符串中,包含v这个子串            //那么v作为lcp的贡献就有C(2,sum[v])             q.push( v );        }    }}int main(){    scanf("%d", &n);    rot = cnt = 1;    for(int i=1; i<=n; i++){        scanf("%s", s);        insert( s );    }    query();    cout << ans << endl;}
原创粉丝点击