感覺很水。
因為sam上乙個點的子樹大小代表這個點所表示子串的出現次數。
建出廣義字尾自動機之後。在\(parent\)樹上跑\(dp\),維護\(size[i][1]\),和\(size[i][0]\)代表i的子樹中有多少第乙個串的結束節點和第二個串的結束節點,然後答案就是\(size[i][0]*size[i][1]*(len[i]-len[fa[i]])\)。
#include#include#include#include#includeusing namespace std;
const int n=801000;
char s1[n],s2[n];
long long ans;
int cnt,head[n];
struct edgee[n];
void add(int u,int v)
struct sam
void rebuild()
void ins(int c,int k)
} u=x;
} void work(int u)
ans+=(long long)size[u][1]*size[u][2]*(len[u]-len[fa[u]]);
}}sam;
int main()
HAOI2016 找相同字元
給定兩個字串,求出在兩個字串中各取出乙個子串使得這兩個子串相同的方案數。兩個方案不同當且僅當這兩個子串中有乙個位置不同。兩行,兩個字串s1,s2,長度分別為n1,n2。1 n1,n2 200000,字串中只有小寫字母 題解 s1 s2拼起來。求height 要求 i j lcp rk i rk j ...
HAOI2016 找相同字元
其實這道題跟 ahoi2013 差異很像 其實這個問題的本質就是讓你算所有字尾的 lcp 長度之和,但是得來自兩個不同的字串 先把兩個字串拼起來做一遍 sa 由於我們多算了來自於同乙個串內的情況 於是在分別對這兩個串建 sa 減掉這兩次算出來的答案 現在的問題轉化為求出 height 陣列所有子區間...
HAOI 2016 找相同字元
題目鏈結 演算法 首先 子串是字尾的字首 考慮拼接兩個字串 中間用不可見字元隔開 求出該字串的字尾陣列 那麼字首相同的字尾一定排名一定接近 而我們又知道lcp i j min 維護乙個單調遞增的字尾陣列即可 時間複雜度 o nlogn n a b includeusing namespace std...