//cf835d 发现规律+打表
/*
连T几次后才发现规律。。
多写几组看出,k-回文串的必要条件是其本身是回文串,
在这个基础上,只要保证它的左半部分和右半部分分别都是回文串即可。
(如果用左半部分和右半部分比较是否相同必然超时。。)
这样一上来用n^2时间找出所有回文串并标记,接着从小到大枚举k,然后枚举k-回文串推k+1-回文串。
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
#define ll long long 
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define frr(i,a,b) for(int i=a;i>=b;i--)
#define ms(a,b) memset(a,b,sizeof(a))
#define scfd(a) scanf("%d",a)
#define scflf(a) scanf("%lf",a)
#define scfs(a) scanf("%s",a)
#define ptfd(a) printf("%d\n",a)
#define ptfs(a) printf("%s\n",a)
#define showd(a,b) printf(a"=%d\n",b)
#define showlf(a,b) printf(a"=%lf\n",b)
#define shows(a,b) printf(a"=%s\n",b)
#define mmcp(a,b) memcpy(a,b,sizeof(b))
using namespace std;
const int MAXN=5005;
struct pairs{
	int l,r;
	bool operator<(const pairs& a)const{
		if(r-l+1!=a.r-a.l+1)
			return r-l+1<a.r-a.l+1;
		else
			return l<a.l;
	}
}p[MAXN*MAXN/2];
pairs t[MAXN*MAXN/2];
bool ok[MAXN][MAXN];
char s[MAXN];
int len;
int con[MAXN];
int main(){
	// freopen("1.in","r",stdin);
	// freopen("1.out","w",stdout);
	ms(ok,false);
	scfs(s);
	len=strlen(s);
	int l,r;
	fr(i,0,len-1){
		l=r=i;
		while(l>=0&&r<=len-1&&s[l]==s[r]){
			ok[l][r]=true;
			p[con[1]++]=(pairs){l--,r++};
		}
	}
	fr(i,0,len-2){
		l=i,r=i+1;
		while(l>=0&&r<=len-1&&s[l]==s[r]){
			ok[l][r]=true;
			p[con[1]++]=(pairs){l--,r++};
		}
	}
	printf("%d",con[1]);
	fr(i,2,len){
		fr(j,0,con[i-1]-1){
			if(ok[p[j].r+1][p[j].r+1+p[j].r-p[j].l]&&ok[p[j].l][p[j].r+1+p[j].r-p[j].l])	
				t[con[i]++]=(pairs){p[j].l,p[j].r+1+p[j].r-p[j].l};
			if(ok[p[j].r+2][p[j].r+2+p[j].r-p[j].l]&&ok[p[j].l][p[j].r+2+p[j].r-p[j].l])	
				t[con[i]++]=(pairs){p[j].l,p[j].r+2+p[j].r-p[j].l};
		}
		fr(j,0,con[i]-1)
			p[j]=t[j];
		printf(" %d",con[i]);
	}
	printf("\n");
	return 0;
}
 posted on 2017-09-22 17:14  cylcy  阅读(260)  评论(0编辑  收藏  举报