zoukankan      html  css  js  c++  java
  • 【bzoj1174】[Balkan2007]Toponyms

    zz:https://www.cnblogs.com/GXZlegend/p/7134233.html

    题目描述

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

    输入

    第一行给出数字N.N在[2,1000000] 下面N行描述这些字符串,长度不超过20000 。保证输入文件不超过10MB

    输出

    a single line with an integer representing the maximal level of complexity Lc(T).

    样例输入

    7
    Jora de Sus
    Orhei
    Jora de Mijloc
    Joreni
    Jora de Jos
    Japca
    Orheiul Vechi

    样例输出

    24

    题解

    Trie树

    很显然建立Trie树,用 每个节点的深度*对应字符串个数 更新答案。

    但是本题卡空间只有128M,不能使用普通的Trie树存边方式,必须使用邻接表(链式前向星)存边。

    所以每次插入时扫一遍,看能否扫到该字符,并决定是否添加新边。

    时间复杂度O(53len),卡卡常数可以过。另外数组大小已实测。

    #include <iostream> 
    #include <cstdio> 
    #include <cstdlib> 
    #include <cstring> 
    #include <cctype> 
    #include <algorithm> 
    #include <vector> 
    using namespace std; 
    int read() 
    { 
      int x = 0, f = 1; 
      char c = getchar(); 
      while(!isdigit(c))
      {   
         if(c == '-') 
            f = -1; 
         c = getchar(); 
      } 
    while(isdigit(c))
      {   
            x = x * 10 + c - '0'; 
            c = getchar(); 
      }     
    return x * f; 
    } 
    #define maxn 5000010 
    #define LL long long 
    int n, rt, ToT, m, val[maxn], head[maxn], nxt[maxn], to[maxn]; 
    char ec[maxn]; 
    LL ans; 
    void insert() 
    { 
       int u = rt; 
       val[u]++; 
       char C = getchar(); 
       for(int i = 0; C != '
    '; i++, C = getchar()) 
       {    
           int v = -1; 
           for(int e = head[u]; e; e = nxt[e]) 
               if(ec[e] == C) //看是否能找到一个C这样一个子结点 
                  { 
                     v = to[e]; 
                     break; 
                  }  
           if(v < 0) //如果没找到则新加一个 
           {
              to[++m] = ++ToT;
              ec[m] = C;
              nxt[m] = head[u];
              head[u] = m;
              v = ToT; 
           }
           val[u = v]++; 
           ans = max(ans, (LL)val[u] * (i + 1)); 
       } 
       return ; 
    } 
    int main() 
    { 
    n = read(); 
    rt = ToT = 1; 
    for(int i = 1; i <= n; i++) 
        insert(); 
    printf("%lld
    ", ans); 
    return 0; 
    }
  • 相关阅读:
    P4178 Tree
    CF437D The Child and Zoo
    CF1032G Chattering ST表+倍增
    P4165 [SCOI2007]组队 推柿子+差分
    P1450 [HAOI2008]硬币购物 容斥原理+完全背包
    P6275 [USACO20OPEN]Sprinklers 2: Return of the Alfalfa P 轮廓线DP
    P6009 [USACO20JAN]Non-Decreasing Subsequences P 矩阵优化DP
    P2605 [ZJOI2010]基站选址 线段树优化DP
    P5597 【XR-4】复读 思维题 +二叉树合并
    P5304 [GXOI/GZOI2019]旅行者 最短路+位运算优化
  • 原文地址:https://www.cnblogs.com/cutemush/p/12520726.html
Copyright © 2011-2022 走看看