• CodeForces


    题目链接

    题目大意

      给你n个字符串,让你求一个集合,这些集合里的字符串是n个字符串中某些字符串的前缀,并且集合中的字符串任意两个都不相似,相似的定义为其中一个字符串去掉第一个字符和另一个完全相同。

    解题思路

      在字典树上从根到每一个节点的简单路径都是某些字符串的一个前缀,和他相似的点就是fail指针指向的比当前点深度小1的点(因为fail指针的定义是与当前字符串的后缀能匹配的最大前缀长度,深度小1自然就只有第一个不匹配),没有相似的字符串即当前节点i与fail指针指向的结点fail[i]只能选择一个,根据fail指针建出fail树跑树形dp即可。

    代码

    const int maxn = 2e6+10;
    int tr[maxn][26], idx, dep[maxn];
    char str[maxn];
    vector<int> e[maxn];
    void insert() {
        int p = 0;
        for (int i = 0; str[i]; ++i) {
            int t = str[i]-'a';
            if (!tr[p][t]) tr[p][t] = ++idx, dep[idx] = dep[p]+1;
            p = tr[p][t];
        }
    }
    int q[maxn], fail[maxn];
    void build() {
        int tt = -1, hh = 0;
        for (int i = 0; i<26; ++i)
            if (tr[0][i]) q[++tt] = tr[0][i];
        while(hh<=tt) {
            int t = q[hh++];
            for (int i = 0; i<26; ++i) {
                int p = tr[t][i];
                if (!p) tr[t][i] = tr[fail[t]][i];
                else {
                    fail[p] = tr[fail[t]][i];
                    q[++tt] = p;
                }
            }
        }
        for (int i = 0; i<=idx; ++i) clr(tr[i], 0);
    }
    int dp[maxn][2];
    void dfs(int u) {
        //cout << u << endl;
        dp[u][0] = 0, dp[u][1] = 1;
        for (auto v : e[u]) {
            dfs(v);
            dp[u][0] += max(dp[v][0], dp[v][1]);
            dp[u][1] += dp[v][0];
        }
    }
    int main() {
        IOS;
        int __; cin >> __;
        while(__--) {
            idx = 0;
            int n; cin >> n;
            for (int i = 1; i<=n; ++i) {
                cin >> str;
                insert();
            }
            build();
            for (int i = 1; i<=idx; ++i) {
                if (dep[i]==dep[fail[i]]+1) e[fail[i]].push_back(i);
                else e[0].push_back(i);
            }
            dfs(0);
            for (int i = 0; i<=idx; ++i) e[i].clear(), dep[i] = 0, fail[i] = 0;
            cout << dp[0][0] << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    分享完整的项目工程目录结构
    2014年糯米网校
    高并发非自增ID如何设计?
    Asp.Net中使用Couchbase——Memcached缓存使用篇
    协作图(通信图)collaboration diagram
    解决java获取系统时间差8个小时 专题
    智言趣语
    Common class for judge IPV6 or IPV4
    判断参数是否符合要求的一个类
    Connection to https://dl-ssl.google.com refused的解决办法
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/15327444.html
Copyright © 2020-2023  润新知