字典樹 原理:按照每個根向下發散 形成一棵 樹
這個題 需要在每乙個字母處都做統計 (求字首單詞)
開乙個 二維陣列和ant來 模擬樹 root開始為0 作為 起點 t=str[i]-'a'; 作為分支
關鍵就是 ant 這是形成樹的關鍵 ant用來區分每乙個節點 這樣二維陣列 tree才能
真正構建完成(很神奇....)
#include#include#includeusing namespace std;
typedef long long ll;
const ll maxn=1e6+10;
int tree[maxn][26]; 構建父子關係
int cnt=0;//節點區分
int root;
int sum[maxn]=;//統計陣列
void insert(char s)
}int find(char s)
return sum[root];
}int main()
while(cin>>ask)
void insert(int x)
}int find(int y)
return ans;
}int main()
p[maxn];//建樹結構體大小
int size;//節點區分引數
void init()
p[now].cnt++; //統計 單詞 出現的次數
}void build()
v=p[v].fail;//指向自己的失敗指向
}if(v==-1)//為祖先
p[p[u].next[i]].fail=0;
}q.push(p[u].next[i]);//送入先的節點(子類)作為父類 構建fail
} }}}
int get(int u)
return res;
}int match(char *s)
if(p[now].cnt)//是都為樹分支結尾(單詞最後乙個單詞節點)
res+=get(now);//次數累加到總計
} return res;
} /*當時自己看的這段很懵逼 ****
為啥沒有乙個乙個和字串
比較 ...現在想想,笑哭 ```
1.其時有比較操作請看 for()迴圈的第乙個 if()呢就是
比較操作
2.而後來的else 是fail的跳轉 作用就是用來優化比較操作
這一點和 kmp非常相似
*/char s[maxx];//建立單詞陣列
int main()
scanf("%s",s);
build();//樹中各節點 用fail串聯 的建立
printf("%d\n",match(s));
} return 0;
}
字典樹哇 AC自動機哇
字典樹 原理 按照每個根向下發散 形成一棵 樹 這個題 需要在每乙個字母處都做統計 求字首單詞 開乙個 二維陣列和ant來 模擬樹 root開始為0 作為 起點 t str i a 作為分支 關鍵就是 ant 這是形成樹的關鍵 ant用來區分每乙個節點 這樣二維陣列 tree才能 真正構建完成 很神...
AC自動機(KMP 字典樹)
ac自動機 kmp 字典樹 題目 輸入n個串,判斷有多少個搜尋串的子串 in out 1 47a ababc abcd abcde abcdef abcdefg abcd includeusing namespace std char str 1000000 100 struct node root...
字典樹問題與AC自動機
利用字串的公共字首來避免無謂的字串比較,降低查詢時間。字典樹節點 每個節點對應乙個最大可儲存字元陣列。假設字典只存26個小寫英文本母,那麼每個節點下應該有乙個長度為最大26的陣列。換言說,可存的元素型別越多,單個節點占用記憶體越大。如果用字典樹儲存漢字,那麼每個節點必須為數千個常用漢字開闢乙個陣列作...