本題目來自five20的週末考試題。c++
Description算法
給定一個 0/1 序列,求其中知足 " ⺉ " 性質的子串個數。
" ⺉ " 性質解釋:
" ⺉ " 性質的子串知足:將該子串先反轉,再把每位上的數取反(即 0 變 1,1 變 0 )後獲得的新串和原串相同。(舉
例 : 1010 知足 " ⺉ " 性質,由於先變爲 0101 ,再取反爲 1010 和原串相同)
Input Format
第一行只含一個 n ,表示 0/1 序列⻓度。
第二行爲⻓度爲 n 的 0/1 序列。
Output Format
一個數,表示 0/1 序列中知足 " ⺉ " 性質的子序列個數(因爲答案可能很大,對 233333333 取模)。
Sample
Input
7
1011001
Output
6
Explana on
樣例中知足 " ⺉ " 性質的 6 個子序列分別是: 2 個 10 ,2 個 01 ,1 個 1100 ,1 個 011001 。Subtasks
由於題目可能過於毒瘤,若是沒法徹底解決問題,能夠嘗試解決部分子任務。
測試點 N
1 N ≤ 1000
2 N ≤ 1000
3 N ≤ 1000
4 N ≤ 1000
5 N ≤ 10000
6 N ≤ 10000
7 N ≤ 10000
8 N ≤ 10000
9 N = 520520
10 N = 520520
11 N = 520520
12 N = 520520
13 N = 2333333
14 N = 2333333
15 N = 2333333
16 N = 2333333
17 N = 6666666
18 N = 6666666
19 N = 10000000
20 N = 10000000測試
分析:當時考試的時候還覺得這是什麼數位DP的問題(並且當時也沒學manacher,也不太擅長字符串算法什麼的),因爲蒟蒻真的不擅長DP因而就打了個暴力水了25分,而後考完five20大佬說這是manacher算法題。而後今天學了一下manacher,A了這道題。實際上仔細分析這道題比通常的manacher還要簡單一些,把判斷條件改成不等,那麼這樣連中間的插入字符都不須要了,直接一個for循環套個manacher主體就過了。spa
Code:code
//It is made by HolseLee on 30th Apr 2018 //five20's test #include<bits/stdc++.h> using namespace std; const int mod=233333333; const int N=1e7+7; long long n,ans,p[N];char s[N]; int main() { freopen("ghost.in","r",stdin); freopen("ghost.out","w",stdout); scanf("%lld%s",&n,s+1);long long id,mx=0; for(int i=1;i<=n;i++){ if(i<mx)p[i]=min(p[id*2-i],mx-i); while(i+p[i]+1<=n&&i-p[i]>=1&&s[i+p[i]+1]!=s[i-p[i]])p[i]++; if(p[i]+i>mx)id=i,mx=p[i]+i; ans=(ans+p[i])%mod;} printf("%lld",ans);return 0; }