zoukankan      html  css  js  c++  java
  • BZOJ1174

    题意

    给你一个字符集合,你从其中找出一些字符串出来. 希望你找出来的这些字符串的最长公共前缀*字符串的总个数最大化.

    思路

    先建好trie树,然后dfs预处理每个子树下单词个数,同时计算最大值即可。

    但是因为数据很大,字符可能的种类很多,要用tr树要用邻接表实现。实测vector也不行。

    #include <bits/stdc++.h>
    
    #define endl '
    '
    #define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
    #define FILE freopen(".//data_generator//in.txt","r",stdin),freopen("res.txt","w",stdout)
    #define FI freopen(".//data_generator//in.txt","r",stdin)
    #define FO freopen("res.txt","w",stdout)
    #define pb push_back
    #define mp make_pair
    #define seteps(N) fixed << setprecision(N) 
    typedef long long ll;
    
    using namespace std;
    /*-----------------------------------------------------------------*/
    
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    #define INF 0x3f3f3f3f
    
    const int N = 5e6 + 10;
    const double eps = 1e-5;
    
    struct node {
        char p;
        int nt, ne;
    };
    
    int head[N];
    node tr[N];
    bool flag[N];
    string s;
    int si;
    int ct;
    ll ans;
    
    void insert(const char str[]) {
        int cur = 0;
        for(int i = 0; str[i]; i++) {
            bool found = false;
            char p = str[i];
            for(int e = head[cur]; e; e = tr[e].ne) {
                if(tr[e].p == p) {
                    cur = tr[e].nt;
                    found = true;
                    break;
                }
            }
            if(!found) {
                tr[++si] = node {p, ++ct, head[cur]};
                head[cur] = si;
                cur = ct;
            }
        }
        flag[cur] = 1;
    }
    
    int dfs(int cur, int dep) {
        int cnt = flag[cur];
        for(int e = head[cur]; e; e = tr[e].ne) {
            cnt += dfs(tr[e].nt, dep + 1);
        }
        ans = max(ans, 1ll * dep * cnt);
        return cnt;
    }
    
    int main() {
        //FI;
        IOS;
        int n;
        cin >> n;
        cin.ignore();
        for(int i = 1; i <= n; i++) {
            getline(cin, s);
            insert(s.c_str());
        }
        dfs(0, 0);
        cout << ans << endl;
    } 
    
  • 相关阅读:
    分组声明
    描述项目的典型用户与场景
    用户调研
    10-11-12
    Sprint--5.21
    Cosplay之孩子的妈咪
    作业5.1之5.2
    51nod 1393 1393 0和1相等串
    51nod 1090 3个数和为0(排序+二分)
    51nod 1095 Anigram单词(map的使用)
  • 原文地址:https://www.cnblogs.com/limil/p/13499095.html
Copyright © 2011-2022 走看看