洛谷P5829 失配樹

2022-06-19 19:21:11 字數 1133 閱讀 1478

給定一長為 \(n(n\leq 10^6)\) 的字串 \(s\),\(m(m\leq 5\times 10^5)\)次詢問,每次詢問它的兩個字首的最長公共 border。

先跑一遍kmp求出\(fail\)陣列,每個\(pos\)向\(fail[pos]\)連邊,建出\(fail\)樹,在\(fail\)樹上求lca即為兩個字首的最長公共border。

#include #include #include #include #include #include using namespace std;

#define rg register int

#define ll long long

templateinline void read(elemtype &t)

while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();

t=(w?-x:x);

}const int maxn=1000010;

struct graph;

edge g[maxn<<1];

int head[maxn];

int cnt;

graph():cnt(2){}

void clear(int node_num=0)

void add_edge(int u,int v)

};namespace kmp

inline void get_fail()

}};graph g;

char s[maxn];

int fail[maxn];

int n,m;

int deep[1000010],anc[1000010][20];

void dfs_init(int u,int fa)

return;

}int lca(int u,int v)

if(u==v) return u;

for(rg i=19;i>=0;--i)

}return anc[u][0];

}int main()

dfs_init(n+1,0);

read(m);

while(m--)

}return 0;

}

P5829 模板 失配樹

p5829 模板 失配樹 參考題解 我們先想乙個問題 如何求出乙個字串的所有border?如果乙個字串既是 s的字首又是 s 的字尾,那麼我們把 ss 自己平移一下就可以前後重合,然後我們就可以繼續匹。這不就是kmp嗎 求兩個字首的最長公共border,先對原串進行kmp,通過跳兩個字首的next求...

P5829 模板 失配樹

p5829 模板 失配樹 求公共 border 求 border 我會,kmp 那麼我直接做 m 次 kmp。顯然會tle,但是我們也可以用 kmp 先求一下原串的 border 然後我們可以發現,border 的 border 也是 border 那麼我們可以利用這個關係建一棵樹,然後我們可以發現...

P5829 模板 失配樹

目錄雖然不知道失配樹是什麼,看這題是為數不多的kmp練手的 能做的題 之一,就把這道題切了 傳送門個人覺得題目已經非常簡潔明瞭,感動,就不再重複題意 kmp lca 先推一道題,對這題應該有幫助 傳送門 kmp中,next i 是由next 1 i 1 得到的,若next i 由next j 得到,...