HEAT OJ #39. 【2020.9.3 NOIP模擬賽 T3】C
阿新 • • 發佈:2020-09-04
題意簡述
給一長為 \(10^6\) 的字串,求有多少子串能夠看作合法括號序列(要求配對的“括號”字母相同)。
題解
模擬賽的重大失誤 給了70還是很不錯的,總比寫掛爆零強
首先看到括號序列要想棧,能配對儘可能配對,這樣就可以做到 \(O(n^2)\) 了。
現在我們換一種思路,對於每一個字首,找合法字尾個數。顯然我們可以設 \(f(i)\) 表示以 \(i\) 為結尾的合法字尾個數,那麼 \(f(i) = f(p) + 1\),其中 \(p\) 表示最靠後的那個合法位置。若能快速求 \(p\),即可 \(O(n)\) DP。
我們現在的問題是,求 \(g(i,c)\)(在 \(i\) 及之前的第一個 \(c\)
程式碼:
for (register int i = 1; i <= n; ++i) { int c = s[i] - 'a', pre = g[i - 1][c] - 1; g[i][c] = i; if (pre < 0) continue; f[i] = f[pre] + 1; ans += f[i]; memcpy(g[i], g[pre], sizeof(g[pre])); g[i][c] = i; }
明明這種題我去年CSP還會呢怎麼現在不會了\kk