YBTOJ 不交回文串

2022-06-13 13:42:14 字數 1185 閱讀 6460

給定字串 \(s\),求有多少對不相交的回文串。

對於 \(100\%\) 的資料,\(1 \leq |s| \leq 10 ^ 5\)。

設 \(pre_i,suf_i\) 分別表示以 \(i\) 為開頭的回文串的個數和以 \(i\) 為結尾的回文串的個數,那麼答案就是:

\[\sum_^}pre_i\sum_^suf_j

\]但這個時間複雜度是 \(\mathcal(n^2)\) 的,不能接受。所以設 \(sum_i=\sum_^suf_j\)。通過字首和就可以達到 \(\mathcal(n)\) 的時間複雜度了。

接下來就是求這幾個陣列了。考慮用 manacher 演算法先計算出以 \(i\) 為中心的回文串半徑 \(a_i\),那麼 \(\frac\) 就是以 \(i\) 為中心的回文個數。可以得到 \(\frac\) 可以為 \(pre_j,suf_k\quad(j\in[i,\text],k\in[1,i])\) 貢獻。這裡可以用差分優化。

int n;

char s[n], c[n];

ll suf[n], pre[n], sum[n], a[n], ans;

int main()

// manacher

memset (suf, 0, sizeof suf);

memset (pre, 0, sizeof pre);

memset (sum, 0, sizeof sum);

for (int i = 1; i <= 2 * n; i ++)

for (int i = 2 * n; i; --i)

for (int i = n; i; --i) pre[i] += pre[i + 1];

for (int i = 1; i <= n; ++i) suf[i] += suf[i - 1], sum[i] = sum[i - 1] + suf[i];

ans = 0;

for (int i = 1; i <= n; i++)

ans += pre[i] * sum[i - 1];

printf ("%lld\n", ans);

memset (s, 0, sizeof s);

memset (c, 0, sizeof c);

memset (a, 0, sizeof a);

} return 0;

}

馬拉車 相交回文串,最長雙回文串問題

manacher 演算法流程 為了不判斷奇偶,方便比較,在原字串裡新增一些特殊字元 明確幾個變數,r 代表我遍歷過的位置中回文串能延伸的最遠位置,mid 是 r 對應的中心位置,那麼 mid 對應的左端點就是 2mid r f i 表示 i 為中心的回文半徑長度 接下來就分以下情況討論,可以自己畫圖...

YbtOJ高效高階 雜湊 2 回文子串

ybtoj高效高階 雜湊 2 如果乙個字串正著讀和倒著讀是一樣的,則稱它是回文的。給定乙個長度為 n的字串s,求他的最長回文子串的長度是多少。abcbabcbabcba abacacbaaaab endcase 1 13 case 2 6正反兩遍求出hash值,然後列舉點向兩邊二分求出最大長度 in...

hdu5157 不交叉回文對統計

將新陣列的元素掃瞄一遍,標記需要更新點的起始和末了位置,起點 終點 最後統計以第i個字元為起點的數量時,將前i個累加起來即可。因為在 起點,終點 區間的元素都加上了起點的那個1,不在 起點,終點 區間的元素由於終點 1,因此沒有加到終點的那個1。本題需要考慮奇偶分類和邊界調節考慮等,十分繁雜,無力o...