题意:给出一个由小写字母组成的长为n的字符串S,定义他的子串【L,R】为周驿东串当且仅当【L,R】为回文串且【L,(L+R)/2】为回文串
求i=【1,n】 所有长度为i的周驿东串的个数
n<=3e5
思路:PAM把所有回文串找出来,记录一下在原串S中的位置和长度,最后check每个结点是不是周驿东串
check部分可以正反两次哈希,N=3e5应该要双哈
我是用manacher预处理出每个位置为中心的回文串的最大长度,check就直接看一下(l+mid)/2这个位置的长度有没有r-mid+1
std里还判了右半部分,迷惑行为
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 typedef pair<ll,ll>P; 11 #define N 700010 12 #define M 200010 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pi acos(-1) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 20 #define lowbit(x) x&(-x) 21 #define Rand (rand()*(1<<16)+rand()) 22 #define id(x) ((x)<=B?(x):m-n/(x)+1) 23 #define ls p<<1 24 #define rs p<<1|1 25 26 const ll MOD=1e9+7,inv2=(MOD+1)/2; 27 double eps=1e-4; 28 ll INF=1ll<<60; 29 ll inf=5e13; 30 int dx[4]={-1,1,0,0}; 31 int dy[4]={0,0,-1,1}; 32 33 char s[N]; 34 int ans[N],aid[N],p[N],a[N],ID; 35 36 int read() 37 { 38 int v=0,f=1; 39 char c=getchar(); 40 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 41 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 42 return v*f; 43 } 44 45 void manacher(char *ch,int len) 46 { 47 rep(i,1,len*2+10) a[i]=-1; 48 int n=2; a[1]=26; a[2]=27; 49 rep(i,1,len) 50 { 51 a[++n]=ch[i]-'a'; aid[i]=n; 52 a[++n]=27; 53 } 54 a[++n]=28; 55 rep(i,0,n) p[i]=0; 56 int mx=0,id=0; 57 rep(i,2,n-1) 58 { 59 if(mx>i) p[i]=min(p[2*id-i],mx-i); 60 else p[i]=1; 61 while(a[i+p[i]]==a[i-p[i]]) p[i]++; 62 if(p[i]+i>mx) 63 { 64 mx=p[i]+i; 65 id=i; 66 } 67 } 68 rep(i,2,n-1) p[i]--; 69 } 70 71 int isok(int l,int r) 72 { 73 int mid=(l+r)>>1; 74 int t=(p[(aid[l]+aid[mid])>>1]>=mid-l+1); 75 return t; 76 } 77 78 struct pam 79 { 80 int q,p,cnt[N],num[N],f[N],len[N],id[N],ch[N][26]; 81 82 pam(){} 83 84 void init() 85 { 86 rep(i,0,ID) 87 { 88 len[i]=f[i]=num[i]=id[i]=cnt[i]=0; 89 rep(j,0,25) ch[i][j]=0; 90 } 91 ID=1; 92 f[0]=f[1]=1; len[1]=-1; 93 } 94 95 void add(int x,int n) 96 { 97 while(s[n-len[p]-1]!=s[n]) p=f[p]; 98 if(!ch[p][x]) 99 { 100 int q=++ID,k=f[p]; 101 len[q]=len[p]+2; 102 while(s[n-len[k]-1]!=s[n]) k=f[k]; 103 f[q]=ch[k][x]; 104 ch[p][x]=q; 105 num[q]=num[f[q]]+1; 106 } 107 p=ch[p][x]; 108 cnt[p]++; 109 id[p]=n; 110 } 111 112 void solve() 113 { 114 per(i,ID,0) cnt[f[i]]+=cnt[i]; 115 rep(i,0,ID) 116 if(len[i]>0) 117 ans[len[i]]+=isok(id[i]-len[i]+1,id[i])*cnt[i]; 118 } 119 }pam; 120 121 122 123 int main() 124 { 125 while(scanf("%s",s+1)!=EOF) 126 { 127 int n=strlen(s+1); 128 pam.init(); 129 rep(i,1,n) ans[i]=0; 130 rep(i,1,n) pam.add(s[i]-'a',i); 131 manacher(s,n); 132 pam.solve(); 133 rep(i,1,n-1) printf("%d ",ans[i]); 134 printf("%d ",ans[n]); 135 } 136 137 return 0; 138 }