【字符串】【Trie】lcp 题解

来源:互联网 发布:java做爬虫 编辑:程序博客网 时间:2024/06/07 08:40

0<i<ni<jnlcp(si,sj)
建立Trie树暴力跑一下,点上用组合数计算结果

#include <iostream>#include <sstream>#include <cstdio>#include <cstdlib>#include <ctime>#include <cmath>#include <cctype>#include <cstring>#include <algorithm>#include <map>#ifndef WIN32#define Auto "%lld"#else#define Auto "%I64d"#endifusing namespace std;typedef class TrieNode {    public:        map<int, TrieNode*> next;        int val;        int ends;        TrieNode():val(0), ends(0) {        }}TrieNode;#define lim 1000005TrieNode pool[lim];TrieNode* top = pool;inline TrieNode* newnode() {    return top++;}typedef class Trie {    public:        TrieNode* root;        Trie():root(newnode()) {}        inline void insert(char *str) {            TrieNode* p = root;            for(char *ch = str; *ch; ch++) {                int c = *ch - 'a';                p->val++;                if(!p->next[c])                    p->next[c] = newnode();                p = p->next[c];            }            p->val++;            p->ends++;        }}Trie;long long res = 0;typedef map<int, TrieNode*>::iterator mii;void getRes(TrieNode*& node, int len) {    for(mii i = node->next.begin(); i != node->next.end(); i++)        for(mii j = i; j != node->next.end(); j++)            if(j != i)                res += i->second->val * 1LL * j->second->val * len;    for(mii i = node->next.begin(); i != node->next.end(); i++)            getRes(i->second, len + 1);    if(node->ends)        res += (node->val - node->ends) * 1LL * node->ends * len,        res += node->ends * 1LL * (node->ends - 1) / 2 * len;}int n;char buf[lim];Trie trie;inline void init() {    scanf("%d", &n);    for(int i = 1; i <= n; i++)        scanf("%s", buf), trie.insert(buf);}inline void solve() {    getRes(trie.root, 0);    printf(Auto, res);}int main() {    init();    solve();    return 0;}