這個題感覺很神呀。將 fft 和 manacher 有機結合在了一起。
首先我們不管那個 「不能連續」 的條件,那麼我們就可以求出有多少對字母關於某一條直線對稱,然後記 $t_i$ 為關於直線 $i$ 對稱的字母對的數量,那麼答案(暫記為 $ans$)就會是:
$$ans = \sum 2^-1$$
在不管那個 「不能連續」 的條件的時候,這個應該是顯然的。
怎麼算的話,我們弄兩次。分別把 $a$ 和 $b$ 當做 $1$,另乙個當做 $0$,然後就可以得到乙個多項式,將這個多項式平方一下就可以得到所有的 $t_i$ 了,具體用 fft 實現。
那麼我們來管一管這個條件。
我們就可以用 manacher 求出每一條直線的最長回文半徑,然後記 $r_i$ 為直線 $i$ 的最長回文半徑,那麼實際上的總答案就會是:
$$ans - \sum r_i$$
然後就做完啦。令 $n$ 為字串的長度:
時間複雜度 $o(n\log n)$,空間複雜度 $o(n)$。
1 #include 2 #include 3 #include 43160_gromahusing
namespace
std;
5 typedef long
long
ll;6
#define n 262144 + 5
7#define _mod 1000000007
8#define mod 998244353
9#define g 3
1011
int n, len, inv_len, d, ans, e[2
][n], rev[n], a[n], t[n], r[n];
12char
s[n];
1314 inline int inc(int u, int v, int
p)15
1819 inline int power(int u, int v, int
p)20
27return
res;28}
2930 inline void
fft_prepare()
3144}45
46 inline void fft(int *p, int
op)4759}
6061 inline void fft_work(char
key)
6273
74 inline void
manacher()
7588}89
90int
main()
91102
manacher();
103for (int i = 0; i <= (n << 1); i ++)
104 ans = inc(ans, _mod - r[i] / 2
, _mod);
105 printf("
%d\n
", ans);
106107
return0;
108 }
BZOJ3160 萬徑人蹤滅
對於每個可以作為對稱軸的位置,我們算出以其為對稱軸有多少對位置和字元是對稱的,設為t i 若不考慮不能連續,則我們可以從這t i 對里任選出來任意對,都是可行的答案,且不重不漏,所以不考慮不能連續的情況的答案為sigma 2 t i 1,考慮不能是連續子串,再減去回文子串的數量即可 回文子串數量ma...
BZOJ 3160 萬徑人蹤滅
給定乙個由 a 和 b 構成的字串,求不連續回文子串行的個數。正難則反我們考慮容斥。對於連續的回文字串顯然是一次馬拉車就可以很好的求出來的,那我們設f i 表示以i為中心的對稱字元對數量,顯然答案就是 2 n 1 12f i 1 那麼我們的問題就轉變成了怎麼求出f i 我們考慮當這個字元為a的時候做...
bzoj3160 萬徑人蹤滅
題目在上方鏈結 description input output sample input sample output hint source 2013湖北互測week1 首先將字串中間插入 把他們分隔開 題目要求求不連續的回文串的個數 那麼就用總數減去連續的即可 考慮連續的部分 直接用manach...