LDUOJ 字首(字典樹的鍊錶優化)

2021-10-14 16:02:50 字數 1856 閱讀 4421

原題鏈結

description

給你乙個字串集合,請從中找出一些字串,使得找出來的這些字串的最長公共字首與字串數的總個數的乘積最大化,並輸出這個最大值。

input

輸入檔案的第一行給出字串個數n(1≤n≤1000000),下面n行描述這n個字串,每個字串長度不超過20000,輸入檔案大小在10mb之內

output

輸出一行乙個數,表示最大化的結果

samples

input copy

7jora de sus

orhei

jora de mijloc

joreni

jora de jos

japca

orheiul vechi

output

24hint

資料範圍 1≤n≤1000000

建立trie樹的同時記錄深度和個數,相乘取max就好。

然後,卡記憶體,用二維陣列存不行。

然而,對於本題來說這種方式並不太合適。因為本題中的字母有1000000個,在極端情況下,trie樹中結點的數量也可能到達這個數量級,字符集也沒有規定,所以應該預設為256,如果按照這樣一一種處理方式,所需要的記憶體可能達到9000mb,這顯然大大超出了題中所給的限制,初始化一遍都會超時,如果把結點數開得少–些又有可能只得部分分。

然後就用鍊錶優化吧,這裡用的是鏈式前向星。

樸素版本:

#pragma gcc optimize(2)

#include

using

namespace std;

typedef

long

long ll;

const

int maxn=

1e6+7;

int son[maxn]

[110

],cnt[maxn]

,idx=1;

int res=0;

void

add(string s)

}int

main()

cout

}

優化版本:

#pragma gcc optimize(2)

#include

using

namespace std;

typedef

long

long ll;

const

int maxn=

1e7+7;

struct nodea[maxn]

;int h[maxn]

,idx,cnt[maxn]

;int tot=1;

void

add(

int u,

int v,

int w)

;h[u]

=idx++;}

int res=0;

void

insert

(string s)

if(p==t) p=

++tot,

add(t,p,s[i]);

cnt[p]++;

res=

max(res,cnt[p]

*(i+1)

);}}

intmain()

cout

}

然後牛客的時限給了1s,沒卡過去。lduoj的給了2s。

HDU 單詞的字首 字典樹

要求輸出每個單詞在不產生歧義的情況下的最短字首,直接構造出一顆字典樹就可以了。先執行插入操作,對每乙個單詞經過的路徑都進行乙個自增的操作。再一次搜尋每乙個單詞,當其遇到覆蓋次數為一,或者是到了單詞末尾就輸出。如下 include include include include using names...

HDU 單詞的字首 字典樹

要求輸出每個單詞在不產生歧義的情況下的最短字首,直接構造出一顆字典樹就可以了。先執行插入操作,對每乙個單詞經過的路徑都進行乙個自增的操作。再一次搜尋每乙個單詞,當其遇到覆蓋次數為一,或者是到了單詞末尾就輸出。如下 include include include include using names...

字典樹(字首樹)的操作

trie樹,即字典樹.常用於搜尋提示。核心思想 空間換時間。利用字串的公共字首來降低查詢時間的開銷從而提高效率。3個特點 樹的定義 public class trie public trienode char val 樹的根節點 trienode root 初始化trie資料結構 public tr...