题目链接:
Palindrome
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 113 Accepted Submission(s): 44
Problem Description
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) is one-and-half palindromic if and only if it satisfies S[i]=S[2n−i]=S[2n+i−2](1≤i≤n).For example, abcbabc is one-and-half palindromic string, and abccbaabc 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 500000), 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
题意:问题目描述的字串有多少个?
思路:可以发现这种字符串是关于S[n]和S[2n-1]对称的,所以枚举S[2n-1],看在S[2n-1]的半径范围内有多少个S[n]的半径范围包括S[2n-1],可以manacher找到半径,然后树状数组求答案;
AC代码:
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=5e5+10; char s[maxn]; int r[maxn],sum[maxn],n; struct cmp { bool operator()(int x,int y) { return x+r[x]>y+r[y]; } }; priority_queue<int,vector<int>,cmp>qu; inline int lowbit(int x){return x&(-x);} inline void update(int x,int num) { while(x<=n) { sum[x]+=num; x+=lowbit(x); } return ; } inline int query(int x) { int ans=0; while(x) { ans+=sum[x]; x-=lowbit(x); } return ans; } int main() { int T;scanf("%d ",&T); while(T--) { gets(s); n=strlen(s); for(int i=n;i>0;i--)s[i]=s[i-1],sum[i]=0; s[0]='#';s[n+1]=' '; int mx=0,id=0; for(int i=1;i<=n;i++) { if(mx>i)r[i]=(r[2*id-i]<(mx-i)?r[2*id-i]:(mx-i)); else r[i]=1; while(s[i-r[i]]==s[i+r[i]])r[i]++; if(i+r[i]>mx)mx=i+r[i],id=i; } for(int i=1;i<=n;i++)r[i]--; LL ans=0;int num=0; while(!qu.empty())qu.pop(); qu.push(1);update(1,1);num++; for(int i=2;i<=n;i++) { while(!qu.empty()) { int fr=qu.top(); if(fr+r[fr]<i) { qu.pop(); num--; update(fr,-1); } else break; } ans=ans+num-query(i-r[i]-1); qu.push(i);update(i,1);num++; } printf("%lld ",ans); } return 0; }