關於維護AC自動機fail樹的三道題目

2021-06-20 02:14:07 字數 3396 閱讀 8447

由易到難

e-government cf 163e

gre words hdu 4117 

這題本來的做法是ac自動機優化dp,然而hdu加入了新的資料,估計構造了一些會導致fail鏈很長的資料,以前的做法會tle,這就又需要我們維護fail樹,用線段樹維護fail樹的dfs序列,支援單點修改區間求最值。需要注意的是當fail鏈比較短時(比如這題的原始資料),用線段樹維護做法反而耗時更長。

一開始交上去各種優化各種mle,後來發現原來是ac自動機初始化一下把整個陣列置空了,特意找了篇oj判mle的方法從這種情況來看,hdu用的方法應該和bnuoj一樣

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #pragma comment(linker, "/stack:102400000,102400000")

using std::priority_queue;

using std::vector;

using std::swap;

using std::stack;

using std::sort;

using std::max;

using std::min;

using std::pair;

using std::map;

using std::string;

using std::cin;

using std::cout;

using std::set;

using std::queue;

using std::string;

using std::stringstream;

using std::make_pair;

using std::getline;

using std::greater;

using std::endl;

using std::multimap;

using std::deque;

using std::unique;

using std::lower_bound;

using std::random_shuffle;

using std::bitset;

using std::upper_bound;

using std::multiset;

using std::ios;

using std::make_heap;

using std::push_heap;

using std::pop_heap;

typedef long long ll;

typedef unsigned long long ull;

typedef unsigned un;

typedef pairpair;

typedef multimapmmap;

typedef long double lf;

const int maxn(300010);

const int maxm(20010);

const int maxe(2100010);

const int maxk(6);

const int hsize(1313131);

const int sigma_size(26);

const int maxh(18);

const int infi((int_max-1) >> 1);

const ull base(31);

const ll lim(1e13);

const int inv(-10000);

const int mod(1000000007);

const double eps(1e-7);

const lf pi(acos(-1.0));

templateinline bool checkmax(t &a, t b) return false;}

templateinline bool checkmin(t &a, t b) return false;}

templateinline t abs(t a)

templateinline bool ez(t a)

struct sgt

inline int rs(int rt)

inline void push_up(int rt)

void build(int l, int r, int rt)

void update(int l, int r, int rt, int qi, int qv)

// push_down(rt);

int m = (l+r) >> 1;

if(qi <= m) update(l, m, ls(rt), qi, qv);

else update(m+1, r, rs(rt), qi, qv);

push_up(rt);

} int query(int l, int r, int rt, int ql, int qr)

} sgt;

int left[maxn], right[maxn], ind;

struct tree

void insert(int tu, int tv)

void dfs(int u)

} tree;

int po[maxm], sco[maxm];

int front, back;

struct ac

void insert(char *sp, int i)

rt = ch[rt][id];

} po[i] = rt;

} void construct()

while(front < back)

else

ch[cur][i] = ch[f[cur]][i];

}} ind = 0;

tree.dfs(0);

}} ac;

char str[maxn+maxm];

char *tst[maxm];

int main()

ac.construct();

sgt.build(1, ind, 1);

int ans = 0;

for(int i = n-1; i >= 0; --i)

checkmax(ans, temp);

} printf("case #%d: %d\n", ++n_case, ans);

} return 0;

}

阿狸的打字機

有關AC自動機的fail樹

由於ac自動機fail的作用老是忘 在這裡記錄一下,以後複習也方便 首先,再字典樹上,每個點的fail,指向的就是和這個節點所表示的串擁有最長公共字尾的節點 這個的話,在建立完字典樹以後,直接bfs就可以弄出來了 然後ac自動機的經典例題,就是詢問x在y裡面出現了多少次 我們先在字典樹上面遍歷y 然...

bzoj3172 AC自動機 fail樹

bzoj3172 tjoi2013 單詞 time limit 10 sec memory limit 512 mb 某人讀 一篇 是由許多單詞組成。但他發現乙個單詞會在 中出現很多次,現在想知道每個單詞分別在 中出現多少次。input 第乙個乙個整數n,表示有多少個單詞,接下來n行每行乙個單詞。每...

BZOJ3172 AC自動機 fail樹

description 某人讀 一篇 是由許多單詞組成。但他發現乙個單詞會在 中出現很多次,現在想知道每個單詞分別在 中出現多少次。input 第乙個乙個整數n,表示有多少個單詞,接下來n行每行乙個單詞。每個單詞由小寫字母組成,n 200,單詞長度不超過10 6 output 輸出n個整數,第i行的...