**
定義k-回文串如下:(1)任何串(包括空串)都是0-回文;
(2)乙個長度為n的回文串,若它的前n/2個字元和後n/2個字元都是(k-1)-回文,
則它是k-回文。現給定乙個串(長度不超過5,000,000),
設它的每個字首分別是x-回文,
求所有這些x值的和。
比如abacaba,
」a」是1-回文,
」aba」是2-回文,
」abacaba」是3-回文,故輸出6。
將字串 反轉接在後面,然後kmp求解即可
把原串翻轉後拼接在原來的串後面,用乙個不在字母表中的分隔符隔開的。
然後用kmp裡對模式串的預處理那個過程,求出失配以後往前跳的那個指標。
我們從新串最後乙個位置開始,每向前跳一次都得到乙個回文字首。
比如有這樣乙個串 abaaba…..(後面部分省略),拼接後得到
abaaba......#......abaaba
012345......#......6789ab
則最後位置的失配指標為5,由kmp的意義,也就是說(012345) == (6789ab),而同時由我們的翻轉操作知(012345)==(ba9876),
故(012345)為乙個回文串。從5繼續向前跳到2,同理(012)也是回文串。
由上過程可以把全部回文字首作好標記。然後再從左到右簡單地掃瞄一遍就可以把每個k值計算出來了。
ps:幸虧cf記憶體不怎麼限制,開了三個1kw的陣列啊。。
view code
#include#includeintn,m;
char b[10000010
];int p[10000010
];int d[10000010
];void
getp()
}int
main()
b[2*m+2]='\0'
; m=2*m+1
; getp();
int tmp=p[m];
while
(tmp)
__int64 ans=0
;
for(int i=1;i<=m;i++)
if(ans==0) printf("
1\n"
);
else printf("
%i64d\n
",ans);
}
view code
一種更簡單的方法:雜湊/*l: s[0]*107^2+s[1]*107+s[2];//從前往後雜湊
r: s[0]+s[1]*107+s[2]*107^2;//從後往前雜湊
*/#include
#include
using
namespace
std;
char s[5000010
];int f[5000010
];int
main()
cout
}
雜湊法判斷字串回文
對乙個字串的子字串,判斷回文一般需要o n 的時間,但是如果預先處理出子字串的雜湊值,則可以在o 1 的時間判斷。具體方法是,如果是小寫字母,則可以用26進製數進行記錄。base 26 for ha i ha i 1 base str i a 再反著進行一次雜湊過程 for ha2 i ha2 i ...
CF25E 字串雜湊 KMP
題意 給定三個串,求包含這三個串的總串的最小長度。思路 字串雜湊。當然,也可以用kmp,然而我自己沒有想到,看來對kmp的理解仍然不夠深。這裡也引用一下其他博主的kmp做法。實現 include using namespace std typedef unsigned long long ull c...
兔子與兔子與回文串 字串雜湊
雜湊就是把乙個具有某些性質的東西轉化成另乙個便於查詢的東西。其應用有許多,主要是字串。下面是2個雜湊的字串題。兔子與兔子 一道裸題,不想解釋w,就是了解一些hash在字串中的應用 回文串 這邊有一些小小的變化。先將回文串分成奇偶,然後列舉回文中心,用二分的方法找到以當前字元為中心的回文串最長是多少。...