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
| #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; #define MAXN 600006
int n , lst; char ch[MAXN]; int w[MAXN]; ll ans = 0;
long long tot[MAXN] , res[MAXN]; struct SAM{ int son[MAXN][27]; int par[MAXN] , len[MAXN]; int head[MAXN] , nxt[MAXN<<1] , to[MAXN<<1]; int cnt , ecnt; int sz[MAXN]; void adde( int u , int v ) { to[++ecnt] = v; nxt[ecnt] = head[u]; head[u] = ecnt; } int mx[MAXN] , semx[MAXN] , mn[MAXN] , semn[MAXN]; void init( ) { memset( son , 0 , sizeof son ) , memset( head , -1 , sizeof head ); memset( mx , -0x3f , sizeof mx ) , memset( mn , 0x3f , sizeof mn ); memset( semx , -0x3f , sizeof semx ) , memset( semn , 0x3f , sizeof semn ); cnt = lst = 1; ecnt = 0; } void addall( ) { for( int i = 2 ; i <= cnt ; ++ i ) adde( par[i] , i ); } void ins( int x , int w ) { int cur = ++ cnt; len[cur] = len[lst] + 1 , sz[cur] = 1; mx[cur] = mn[cur] = w; int p = lst; while( p && !son[p][x] ) son[p][x] = cur , p = par[p]; if( !p ) par[cur] = 1; else { int q = son[p][x]; if( len[q] == len[p] + 1 ) par[cur] = q; else { int cl = ++ cnt; memcpy( son[cl] , son[q] , sizeof son[q] ); par[cl] = par[q]; len[cl] = len[p] + 1 , par[q] = par[cur] = cl; for( ; son[p][x] == q ; p = par[p] ) son[p][x] = cl; } } lst = cur; } void dfs( int cur ) { int l = len[cur]; for( int i = head[cur] ; ~i ; i = nxt[i] ) { int v = to[i]; dfs( v ); if( mx[v] > mx[cur] ) semx[cur] = mx[cur] , mx[cur] = mx[v]; else if( mx[v] > semx[cur] ) semx[cur] = mx[v]; if( semx[v] > semx[cur] ) semx[cur] = semx[v];
if( mn[v] < mn[cur] ) semn[cur] = mn[cur] , mn[cur] = mn[v]; else if( mn[v] < semn[cur] ) semn[cur] = mn[v]; if( semn[v] < semn[cur] ) semn[cur] = semn[v]; tot[l] += 1ll * sz[cur] * sz[v]; sz[cur] += sz[v]; } if( semx[cur] > -1e9 - 10 ) res[l] = max( res[l] , 1ll * mx[cur] * semx[cur] ); if( semn[cur] < 1e9 + 10 ) res[l] = max( res[l] , 1ll * mn[cur] * semn[cur] );
} void fuck() { puts("fuck"); } } S ;
int main() { S.init(); cin >> n; scanf("%s",ch); for( int i = 0 ; i < n ; ++ i ) scanf("%d",&w[i]); for( int i = n - 1 ; i >= 0 ; -- i ) S.ins( ch[i] - 'a' , w[i] ); for( int i = 0 ; i <= n ; ++ i ) res[i] = -1e18; S.addall( ) , S.dfs( 1 );
for( int i = n - 1 ; i >= 0 ; -- i ) tot[i] += tot[i + 1] , res[i] = max( res[i] , res[i + 1] ); for( int i = 0 ; i < n ; ++ i ) printf("%lld %lld\n",tot[i],res[i] == -1e18 ? 0 : res[i]); }
|