BZOJ 3160 萬徑人蹤滅 解題報告

2022-08-03 13:51:20 字數 1537 閱讀 1441

這個題感覺很神呀。將 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 4

using

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 }

3160_gromah

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...