6230 Palindrome
Alice like strings, especially long strings. For each string, she has a special evaluation system to judge how elegant the string is. She defines that a string S[1..3n−2](n≥2)S[1..3n−2](n≥2) is one-and-half palindromic if and only if it satisfies S[i]=S[2n−i]=S[2n+i−2](1≤i≤n)S[i]=S[2n−i]=S[2n+i−2](1≤i≤n).For example, abcbabcabcbabc is one-and-half palindromic string, and abccbaabcabccbaabc is not. Now, Alice has generated some long strings. She ask for your help to find how many substrings which is one-and-half palindromic.
Input
The first line is the number of test cases. For each test case, there is only one line containing a string(the length of strings is less than or equal to 500000500000), this string only consists of lowercase letters.
Output
For each test case, output a integer donating the number of one-and-half palindromic substrings.
Sample Input
1 ababcbabccbaabc
Sample Output
2
Hint
In the example input, there are two substrings which are one-and-half palindromic strings, $abab$ and $abcbabc$.
類似於迴文串的一種半迴文串。
這道題要用馬拉車演算法,很遺憾我不會;要用樹狀陣列,很遺憾我也不會。所以……
AC程式碼:
#include <cstring> #include <cstdio> #include <iostream> #include <vector> using namespace std; const int maxn=500010; typedef long long LL; vector <int> ve[maxn]; int a[maxn],n; char s[maxn]; int Len[maxn],tlen[maxn]; int Manacher(char *st,int len) { int mx=0,ans=0,po=0; for(int i=1;i<=len;i++) { if(mx>i) Len[i]=min(mx-i,Len[2*po-i]); else Len[i]=1; while(st[i-Len[i]]==st[i+Len[i]]) Len[i]++; if(Len[i]+i>mx) { mx=Len[i]+i; po=i; } if(ans<Len[i]) ans=Len[i]; } return ans-1; } int lowbit(int x) { return x&(-x); } int add(int pos,int v) { while(pos<=n) { a[pos]+=v; pos+=lowbit(pos); } } int query(int pos) { int ans=0; while(pos) { ans+=a[pos]; pos-=lowbit(pos); } return ans; } int main() { int t; cin>>t; while(t--) { memset(a,0,sizeof(a)); for(int i=0;i<maxn;i++) ve[i].clear(); memset(s,0,sizeof(s)); scanf("%s",s+1); int l=strlen(s+1); s[0]='$'; Manacher(s,l); for(int i=2;i<=l;i++) { tlen[i]=Len[i]-1; ve[i-tlen[i]].push_back(i); } LL ans=0;n=l; for(int i=1;i<=n;i++) { for(int j=0;j<ve[i].size();j++) add(ve[i][j],1); ans+=query(min(i+tlen[i],n))-query(i); } cout<<ans<<endl; } return 0; }