Trie樹原理 模板及例題(更新中)

2021-10-08 03:02:18 字數 4634 閱讀 8277

模板及例題

模板

const

int maxn =

2e6+5;

int tree[maxn][30

];bool flagg[maxn]

;int tot;

void

insert_

(char

*str)

flagg[root]

=true;}

bool

find_

(char

*str)

return

true;}

void

init()

tot=0;

}

例題poj-2513 colored sticks

將一種顏色看成一塊陸地,一根木棍看作一座橋(兩塊陸地之間可以有多座橋),求是否存在一條通路使得經過每座橋一次且僅一次。因此這道題變成尤拉圖的判定,以一種顏色為陸地,每根木棍看作一座橋,使得兩塊陸地的度數分別加1。

在判定顏色時,由於木棍數量較多,若使用stl中的map會超時,因此應改用trie樹。

判定尤拉圖需使用並查集檢查圖是否連通。因此這道題需用到並查集+trie樹

**

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define inf 10000000000000

using

namespace std;

//字典樹:

const

int maxn =

2e6+5;

int tree[maxn][30

];int flagg[maxn]

;int tot;

int color=0;

intinsert_

(char

*str)if(

!flagg[root]

)return flagg[root];}

//並查集模板:

const

int mn=

5e5+10;

int par[mn]

,rank[mn]

;void

init()

}int

find

(int x)

void

unite

(int x,

int y)

else

}char s1[12]

,s2[12]

;int cnt[mn]

;int

main()

int cnt=0;

bool res=

true

;int cmp=

find(1

);for(

int i=

1;i<=color;i++)if

(cnt[i]%2

)cnt++;if

(cnt>2)

break;}

if(cnt!=

0&&cnt!=

2)res=

false;if

(res)

else

return0;

}

poj-1451 t9

注意權值是加在原來的權值上,而不是覆蓋原來的權值。如果是新權值覆蓋舊權值,則不需要用到字典樹,只需要建立乙個字首與權值的對映即可。如果是權值加到原來的權值上,則需要使用字典樹來記錄各個節點的權值。

**

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define inf 10000000000000

using

namespace std;

const

int mn=

2e5+10;

const

double esp=

1e-9

;const

int mod=

1e9+7;

map f;

mapint>cmp;

map<

char

,char

>trans;

const

int maxn =

2e6+5;

int tree[maxn][30

];int sum[maxn]

;bool flagg[maxn]

;int tot;

void

insert_

(char

*str,

int p)

else

if(cmp[num]

==sum[root])}

flagg[root]

=true;}

void

init()

} tot=0;

}int

main()

int m;

scanf

("%d"

,&m)

;printf

("scenario #%d:\n"

,case)

;while

(m--

)else

}printf

("\n");

}printf

("\n");

}return0;

}

hdu 4825

給乙個數,取集合中的乙個數與之求異或,問取哪個數異或後最大。

字典樹與xor問題的結合。

如圖,建立乙個二叉樹,將乙個數轉化為二進位制,從高位到低位將數字放於樹中,樹的乙個葉子節點代表乙個數。高度度為n樹最多能表示 2n+1-1 個正整數。

按題目要求,建樹則將十進位制的數轉化為二進位制,從高位到低位將數字存進樹中。查詢的優先查詢與查詢數數字不同的節點,查到葉子節點即為所求數字。

**

#include

#include

#include

#include

#include

typedef

long

long ll;

using

namespace std;

const

int mn=

1e5+10;

int tree[mn*35]

[2];

int flagg[mn*35]

;int tot;

void

insert_

(int x)

flagg[root]

=x;}

intfind_

(int x)

return flagg[root];}

void

init()

//最後清空,節省時間

tot=0;

//re有可能是這裡的問題

}int

main()

printf

("case #%d:\n"

,c);

while

(m--)}

return0;

}

codeforces 665e

求區間異或大於k的區間數。

對區間做字首異或s[ i ]=s[1] ^ s[2] ^ s[3] ^ … ^ s[ i ],那麼區間( l,r ]的異或和為s[ r ] ^ s[ l ]

參考題解

**

#include

#include

#include

#include

#include

typedef

long

long ll;

using

namespace std;

const

int mn=

1e6+10;

int tree[mn*32]

[2];

ll flagg[mn*32]

;int tot;

int n,k;

void

insert_

(int x)

}ll find_

(int x)

elseif(

!root)

return sum;

}return sum+flagg[root];}

intmain()

cout<

return0;

}

字典樹模板及例題

字典樹 time limit 1000ms memory limit 65536kb problem description 遇到單詞不認識怎麼辦?查字典啊,已知字典中有n個單詞,假設單詞都是由小寫字母組成。現有m個不認識的單詞,詢問這m個單詞是否出現在字典中。input 含有多組測試用例。第一行輸...

Trie字典樹模板及栗子

陣列的實現 include include include include include include include using namespace std const int n 1000000 int ch n 26 val n tot 陣列實現的話,總是拿不準ch陣列的大小,我們不確定生...

左偏樹,原理及模板

左偏樹,leftist tree。首先是乙個堆,即 node node.leftchild node node.rightchild 對於樹中任意乙個節點,左孩子的distance 右孩子的distance。將當前樹補全為擴充套件二叉樹。當前節點到最近的葉子節點的距離即為該節點的distance,維...