[Explanations] P5446 [THUPC2018] and green and strings (manacher)

[Explanations] P5446 [THUPC2018] and green and strings (manacher)

Consider for a string \ (f \) operation, it is to make him into a palindrome string to the last node palindrome center.

Then for a location \ (P \) , if it is a valid location, then it has been doubled when the length is more than doubled when the original string makes \ (T \) appeared once.

  • Times larger than the original length once the string, then \ (P \) is a central palindrome, and \ (P \) palindromic radius reached \ (| T | \)
  • Only two times larger than the original length of the string, then \ (S \) that the point doubling time \ (p '\) is a central palindrome, and \ (p' \) palindromic radius reached \ (| T | \) . However, in order to ensure the legitimacy of the first multiplier, in which case the original \ (P \) palindromic radial position to withstand this \ (1 \) node.
  • Three times as long ...

Thinking recursively, a legal position if and only if this position is a palindrome radius to the top of the right border, or right border of his own legitimate and ask radius to the top border.

Manacher can be implemented, attention to detail, each character is drawn cart for non-auxiliary character, he was the center of the palindrome palindrome boundary string must be a secondary character, to be subtracted \ (1 \) in order to achieve the desired effect .

Complexity \ (O (2 \ sum | S |) \)

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;  typedef long long ll; 
inline int qr(){
      register int ret=0,f=0;
      register char c=getchar();
      while(c<48||c>57)f|=c==45,c=getchar();
      while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
      return f?-ret:ret;
}

const int maxn=1e6+5;
char s[maxn<<1];
bool f[maxn<<1];
int p[maxn<<1],cnt,n;
inline void manacher(){
      s[0]='~',s[cnt=1]='|';
      char c=getchar();
      while(c<'a'||c>'z') c=getchar();
      while(c>='a'&&c<='z') s[++cnt]=c,s[++cnt]='|',c=getchar();
      s[cnt+1]='\0';
      for(int t=1,r=0,mid=0;t<=cnt;++t){
        p[t]=0;
        if(r>=t) p[t]=min(r-t+1,p[(mid<<1)-t]);
        while(s[t-p[t]]==s[t+p[t]]) ++p[t];
        if(t+p[t]-1>r) r=t+p[t]-1,mid=t;
      }
}

int main(){
      n=qr();
      for(int t=1;t<=n;++t){
        manacher();
        f[cnt]=1;
        for(int t=cnt;t;--t) f[t]=0,f[t]=(t+p[t]-1==cnt)||(t-p[t]+1==1&&f[t+p[t]-2]);
        for(int t=2;t<=cnt;t+=2) if(f[t]) printf("%d ",t>>1);
        putchar('\n');
      }
      return 0;
}

Guess you like

Origin www.cnblogs.com/winlere/p/11598697.html