~~ 比 KMP 簡單多了,無腦子選手學不會KMP,不會結論題~~
本身懶得造圖了OI WIKI 真棒
字典樹大概長這麼個亞子
嘔吼真棒ios
字符串:git
struct Trie{ int trie[][] ,Trie_num; void add(char *s){ int now = 0 , for(int i = 1 ; i <= len ;i++) { if(!trie[now][s[i]]) trie[now][s[i]] = +++Trie_num; now = trie[now][s[i]]; } } }
二進制:spa
struct Trie{ int tire[][] ,Tire_num; void add(int x){ int now = 0 , for(int i = 31 ; i >= 0 ;i--) { int ch = (x>>(i)&1); if(!tire[now][ch]) tire[now][ch] = +++Trie now = tire[now][ch]; } } }
例題
題目洛谷也有
這個題就是很顯然的板子code
而後就沒有而後了,你就把它切了(多測不清我是sb)blog
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <string> #define ll long long using namespace std; const int N = 1e6+100; int read() { int s = 0 , f = 0 ; char ch = getchar() ; while(!isdigit(ch)) f |= (ch == '-') , ch = getchar(); while(isdigit(ch)) s = s * 10 + (ch ^ 48) , ch = getchar(); return f ? -s : s; } char s[20]; struct Trie{ int Tir_num ,tir[N][11],vis[N]; int add(char *s) { int len = strlen(s+1), now = 0; bool flag = 0; for(int i = 1 ; i <= len ;i++) { int ch = s[i]-'0'; if(!tir[now][ch]) tir[now][ch] = ++Tir_num; else if(i == len) flag = 1; // cout << Tir_num<<" "; now = tir[now][ch]; if(vis[now]) flag = 1; // cout <<now<<" "<< flag <<" "; } vis[now] = 1; // puts(""); return flag; } void clear(){ memset(tir,0,sizeof(tir)); memset(vis,0,sizeof(vis)); Tir_num = 0; // puts("LKP AK IOI"); } }tire; int main() { int T = read() ; while(T--) { tire.clear(); int n = read(); int cnt = 0; for(int i = 1 ; i <= n;i++){ scanf("%s", s+1); cnt += tire.add(s); } if(cnt) puts("NO"); else puts("YES"); } system("pause"); return 0; }
二進制的例題字符串
void query(int x) { int now = 0 , ans = 0; for(int i = 31 ; i >= 0 ;i-- ) { int ch = ((x >> i) & 1) , temp = ch ^ 1; if(tir[now][temp]) now = tir[now][temp] , ans = ((ans << 1) | 1); else { now = tir[now][ch]; ans <<= 1; } } return ans; }
仍是貼一下完整代碼吧get
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <string> #define ll long long using namespace std; const int N = 4000010; int read() { int s = 0 , f = 0 ; char ch = getchar() ; while(!isdigit(ch)) f |= (ch == '-') , ch = getchar(); while(isdigit(ch)) s = s * 10 + (ch ^ 48) , ch = getchar(); return f ? -s : s; } struct Trie{ int tire[N][2], Tir_num; void add(int x) { int now = 0 ; for(int i = 31 ; i >= 0 ;i--) { int ch = ((x>>i) & 1); if(!tire[now][ch]) tire[now][ch] = ++Tir_num; now = tire[now][ch]; } } int query(int x){ int now = 0 , ans = 0; for(int i = 31 ; i >= 0 ;i--) { int ch = ( (x >> i) & 1) , temp = ch ^ 1; if(tire[now][temp]) now = tire[now][temp],ans = (ans << 1) | 1; else now = tire[now][ch], ans <<= 1; } return ans; } }tir; int a[N]; int main() { int n = read(); int ans = -1; for(int i = 1 ; i <= n ;i++) { a[i] = read(); tir.add(a[i]); ans = max(ans,tir.query(a[i])); } printf("%d",ans); system("pause"); return 0; }
踹樹能作的AC自動機也能幹,好吧Tire樹AC自動機的一部分
本身說的僅僅是一部分,OI wiki講的很詳細,對題目分類講的也很詳細,以爲我寫的很差能夠去OI wikistring