1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <queue> #include <cmath> #include <set> #include <map> #define mp make_pair #define pb push_back #define pii pair<int,int> #define link(x) for(edge *j=h[x];j;j=j->next) #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=2e6+10; const double eps=1e-8; const int mod=1e9+9; #define ll long long using namespace std; const int mod1=1e9+7; const int mod2=1e9+9; struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e; void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;} ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; }
char str[MAXN]; int n; ll sum1[MAXN],sum2[MAXN]; ll Sum1[MAXN],Sum2[MAXN]; bool judge(int x1,int y1,int x2,int y2){ ll ans1=(sum1[y1]-sum1[x1-1]*Sum1[y1-x1+1]%mod1+mod1)%mod1; ll ans2=(sum1[y2]-sum1[x2-1]*Sum1[y2-x2+1]%mod1+mod1)%mod1; if(ans1!=ans2)return false; ans1=(sum2[y1]-sum2[x1-1]*Sum2[y1-x1+1]%mod2+mod2)%mod2; ans2=(sum2[y2]-sum2[x2-1]*Sum2[y2-x2+1]%mod2+mod2)%mod2; if(ans1!=ans2)return false; return true; }
bool check(int t,int x,int y){ int len=x-t+1; if(y+len-1>n)return false; if(!judge(t,x,y-x+t,y))return false; if(!judge(x,x+len-1,y,y+len-1))return false; return true; }
int maxx[MAXN<<2]; void push(int x){ if(maxx[x]!=0){ maxx[x<<1]=max(maxx[x<<1],maxx[x]); maxx[x<<1|1]=max(maxx[x<<1|1],maxx[x]); maxx[x]=0; } } void update(int x,int l,int r,int ql,int qr,int t){ if(ql<=l&&r<=qr){maxx[x]=max(maxx[x],t);return ;} int mid=(l+r)>>1; push(x); if(ql<=mid)update(x<<1,l,mid,ql,qr,t); if(qr>mid)update(x<<1|1,mid+1,r,ql,qr,t); } vector<int>vec; void query(int x,int l,int r){ if(l==r){vec.pb(max(-1,(maxx[x]-l)*2+1));return ;} int mid=(l+r)>>1; push(x); query(x<<1,l,mid); query(x<<1|1,mid+1,r); } int main(){ n=read();scanf("%s",str+1); Sum1[0]=Sum2[0]=1; inc(i,1,n)Sum1[i]=Sum1[i-1]*131%mod1,Sum2[i]=Sum2[i-1]*233%mod2; inc(i,1,n)sum1[i]=sum1[i-1]*131+str[i],sum1[i]%=mod1; inc(i,1,n)sum2[i]=sum2[i-1]*233+str[i],sum2[i]%=mod2; int x,y;x=y=(n-1)/2+1; if(n%2==0)y++;else x--,y++; dec(i,(n-1)/2+1,1){ int l=1;int r=x;int ans=0; while(l<=r){ int mid=(l+r)>>1; if(check(mid,x,y))ans=mid,r=mid-1; else l=mid+1; } if(!ans){x--;y++;continue;} update(1,1,n,ans,x,x); x--;y++; } query(1,1,n); for(int i=1;i<=(n-1)/2+1;i++)printf("%d ",vec[i-1]); printf("\n"); return 0; }
|