BZOJ1174 [Balkan2007] Toponyms 邻接链表优化 TRIE树

大家都吼强,可与之共勉嗯嗯。

题意:
  给您一个字符集合,你从其中找出一些字符串出来。 希望你找出来的这些字符串的最长公共前缀 × 字符串的总个数最大化。

  空格也是嗯,所以我看不懂样例!!!!!!!!

题解:
  傻逼题,哎呀MLE了。怎么办,那就暴力找转移叭!!!
  我们发现转移 go[cur][26] 并不是 26 个都用上了(又不是补全AC自动机),于是我萌就可以用链表存转移边。
  A掉惹!!!

/**************************************************************
    Problem: 1174
    User: Lazer2001
    Language: C++
    Result: Accepted
    Time:4716 ms
    Memory:98944 kb
****************************************************************/

# include <bits/stdc++.h>

# define N 5000010

struct edge  {
    char c ; int to, nxt ;  
} g [N] ;

int cnt [N], ncnt ;
int head [N], ecnt ;

# undef N

long long ans ( 0 ) ;

inline void insert ( )  {
    int cur ( 0 ) ;
    register int c ;
    while ( isspace ( c = getchar ( ) ) ) ;
    for ( int i = 1 ; c != '\n' ; ++ i, c = getchar ( ) )  {
        int nxt = -1 ;
        for ( int it = head [cur] ; it ; it = g [it].nxt )
            if ( g [it].c == c )  {
                nxt = g [it].to ;
                break ;
            }
        if ( nxt == -1 )  {
            ++ ecnt ;
            g [ecnt].c = c, g [ecnt].to = ( nxt = ++ ncnt ), g [ecnt].nxt = head [cur] ;  head [cur] = ecnt ;
        }
        cur = nxt ;
        ++ cnt [cur] ;
        ans = std :: max ( ans, 1LL * ( cnt [cur] ) * i ) ;
    }
}

int main ( )  {
    int n ;
    scanf ( "%d", & n ) ;
    while ( n -- )  {
        insert ( ) ;
    }
    printf ( "%lld\n", ans ) ;
    return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值