后缀自动机+线段树乱搞竟然1A,神奇…
#include<bits/stdc++.h>
#define rep(i,k,n) for(int i=k;i<=(n);i++)
#define rep2(i,k,n) for(int i=k;i>=(n);i--)
#define ls x<<1
#define rs x<<1|1
using namespace std;
typedef long long ll;
const int N=600005;
const int inf=0x7f7f7f7f;
const ll inf2=0x7f7f7f7f7f7f7f7full;
struct E{
int to,next;E(int to=0,int next=0):to(to),next(next){}
}edge[N];
int head[N],btot=0;
void add(int x,int y){
edge[++btot]=E(y,head[x]);head[x]=btot;
}
char s[N];
int a[N],n,ch[N][26],len[N],par[N],val[N],last=0,tot=0,sum[N];
ll v[N];
struct data{
ll mx[2];
ll mn[2];
data(){mx[0]=mx[1]=-inf;mn[0]=mn[1]=inf;}
}D[N];
void up(data& a,data b){
data c;
int op1,op2;
op1=op2=0;
rep(i,0,1)c.mx[i]=a.mx[op1]>b.mx[op2] ? a.mx[op1++] : b.mx[op2++];
op1=op2=0;
rep(i,0,1)c.mn[i]=a.mn[op1]<b.mn[op2] ? a.mn[op1++] : b.mn[op2++];
a=c;
}
void ins(int c,int i){int p=last,x,q,nq;
last=x=++tot;
len[x]=len[p]+1;
val[x]=1;
v[x]=a[i];
for(;!ch[p][c];p=par[p])ch[p][c]=x;
if(ch[p][c]!=x){
q=ch[p][c];
if(len[q]==len[p]+1)par[x]=q;
else{
nq=++tot;
len[nq]=len[p]+1;
par[nq]=par[q];
memcpy(ch[nq],ch[q],sizeof(ch[q]));
par[q]=par[x]=nq;
for(;ch[p][c]==q;p=par[p])ch[p][c]=nq;
}
}
}
ll mx[N<<2],ad[N<<2];
void update(int x,int l,int r,int ql,int qr,ll Sum,ll Mx){
if(ql<=l && r<=qr){
ad[x]+=Sum;mx[x]=max(mx[x],Mx);return;
}int mid=(l+r)>>1;
if(ql<=mid)update(ls,l,mid,ql,qr,Sum,Mx);
if(qr>mid)update(rs,mid+1,r,ql,qr,Sum,Mx);
}
ll ans_sum,ans_mx;
void query(int x,int l,int r,int k){
ans_sum+=ad[x];
ans_mx=max(ans_mx,mx[x]);
if(l==r)return;
int mid=(l+r)>>1;
if(k<=mid)query(ls,l,mid,k);
else query(rs,mid+1,r,k);
}
void dp(int x){
sum[x]=val[x];
if(v[x]<inf){
D[x].mx[0]=D[x].mn[0]=v[x];
}
int ok=0;
for(int i=head[x];i;i=edge[i].next){
int v=edge[i].to;
dp(v);
sum[x]+=sum[v];
up(D[x],D[v]);
ok++;
}
ll V=max(D[x].mx[0]*D[x].mx[1],D[x].mn[0]*D[x].mn[1]);
if(ok && x)
update(1,0,n,len[par[x]]+1,len[x],1ll*sum[x]*(sum[x]-1)/2,V);
else if(!x)
update(1,0,n,0,0,1ll*sum[x]*(sum[x]-1)/2,V);
}
void init(){
rep(i,1,tot)add(par[i],i);
memset(mx,-0x7f,sizeof(mx));
dp(0);
}
int main(){
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
scanf("%d",&n);
scanf("%s",s+1);rep(i,1,n)scanf("%d",&a[i]);
int l=n/2;
rep(i,1,l)
swap(s[i],s[n-i+1]),swap(a[i],a[n-i+1]);
memset(v,0x7f,sizeof(v));
rep(i,1,n)
ins(s[i]-'a',i);
init();
rep(i,0,n-1){
ans_sum=0,ans_mx=-inf2;
query(1,0,n,i);
if(!ans_sum)ans_mx=0;
printf("%lld %lld\n",ans_sum,ans_mx);
}
return 0;
}