HDU 6230

Palindrome

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 433    Accepted Submission(s): 168


php

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..3n2](n2) is one-and-half palindromic if and only if it satisfies S[i]=S[2ni]=S[2n+i2](1in).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
Hint
In the example input, there are two substrings which are one-and-half palindromic strings, $abab$ and $abcbabc$.
 

 

Source
題意:
給出一個字符串,求有多少這樣的子字符串 S[1..3n2](n2知足: S[i]=S[2ni]=S[2n+i2](1in),例如 abcbabc 顯然n是奇數。
代碼:
//要求的就是迴文半徑相互覆蓋的點對有多少,manacher預處理出來奇數長度迴文串的中間點的迴文半徑,用優先隊列記錄一下到達j點最遠可以覆
//蓋到的位置,當到達i位置時更新隊列(去掉沒有用了的點,即到達不了i位置的點),樹狀數組求i位置前半徑中有多少相互覆蓋的點並把i加入隊列。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
const int MAXN=500009;
char s[MAXN];
int t,n,p[MAXN<<2],a[MAXN<<2];
struct cmp{
    bool operator () (int &a,int &b)const{
        return a+p[a]>b+p[b];
    }
};
void manacher()
{
    n=strlen(s+1);
    for(int i=1,mx=0,id=0;i<=n;i++){
        p[i]=(mx>i?min(p[id*2-i],mx-i):1);
        while(s[i+p[i]]==s[i-p[i]]) p[i]++;
        if(i+p[i]>mx) { mx=i+p[i];id=i; }
    }
    for(int i=1;i<=n;i++) p[i]--;
}
void add(int id,int c)
{
    while(id<=MAXN-9){
        a[id]+=c;
        id+=((-id)&id);
    }
}
int query(int id)
{
    int s=0;
    while(id){
        s+=a[id];
        id-=((-id)&id);
    }
    return s;
}
int main()
{
    scanf("%d",&t);
    while(t--){
        scanf("%s",s+1);
        manacher();
        memset(a,0,sizeof(a));
        ll ans=0;
        priority_queue<int,vector<int>,cmp>q;
        for(int i=2;i<=n;i++){
            while(!q.empty()){
                int now=q.top();
                if(now+p[now]<i){
                    q.pop();
                    add(now,-1);
                }else break;
            }
            ans+=query(i-1)-query(i-p[i]-1);
            q.push(i);add(i,1);
        }
        printf("%lld\n",ans);
    }
    return 0;
}
相關文章
相關標籤/搜索