題目:
求出關於乙個位置有多少對對稱字母,如果 i 位置有 f[i] 對,對答案的貢獻是 2^f[i] - 1;
然後減去連續的,用 manachar 求出回文長度,每個位置作為邊界都是一種不合法情況;
求對稱,首先把字串中間穿插字元 '$',於是字串的長度變成2倍;
考慮一對字母 s[x],s[y],如果 s[x] = s[y],其對稱中心是 (x+y)/2;
放在加入字元後的字串中,對稱中心就是 x+y;
所以可以看出卷積了:f[i] = ∑(0<=j<=i) (s[j]==s[i-j]),其中 i 視為新字串中的位置,j 和 i-j 視為原字串中的位置;
注意卷積和 manachar 算的個數都要包括自己成對,否則判斷挺麻煩...
這裡卷積的兩個多項式其實是一樣的,所以只要用 fft 算出乙個,然後自己乘起來即可;
做下一步的時候注意清空,別忘了清空 n~lim 部分的值;
處理 bin 的邊界是 n 而非 n-1,因為最多可能有 n 對。
(學習了 manachar 的簡潔寫法)
**如下:
#include#include#include
#include
#include
using
namespace
std;
typedef
double
db;int
const xn=(1
<<19),mod=1e9+7
;db
const pi=acos(-1.0
);int n,rev[xn],lim=1
,l,len[xn],bin[xn],c[xn];
char
ch[xn];
struct
coma[xn],b[xn],aa[xn];
com
operator + (com a,com b);}
com
operator - (com a,com b);}
com
operator * (com a,com b);}
int upt(int x)
void fft(com *a,int
tp);
for(int j=0,len=(mid<<1);jlen)
;for(int k=0;kwn)}}
}void
solve()
char
s[xn];
int manachar()//
+i self
return
ret;
}int
main()
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...