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 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| #include "iostream" #include "algorithm" #include "cstring" #include "cstdio" #include "cmath" #include "vector" #include "map" #include "set" #include "queue" using namespace std; #define MAXN 800006
#define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i) #define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i) #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define pb push_back #define eb emplace_back #define vi vector<int> #define all(x) (x).begin() , (x).end() #define mem( a ) memset( a , 0 , sizeof a ) typedef long long ll; int n , q; char ch[MAXN];
struct SAM { int son[MAXN][26] , par[MAXN] , len[MAXN] , cnt , las; SAM() { cnt = las = 1; } void ins( char a ) { int x = a - 'a' , cur = ++ cnt , p = las; len[cur] = len[p] + 1; 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 ct = ++ cnt; len[ct] = len[p] + 1 , par[ct] = par[q]; memcpy( son[ct] , son[q] , sizeof son[q] ); par[cur] = par[q] = ct; for( ; son[p][x] == q ; p = par[p] ) son[p][x] = ct; } } las = cur; } vi G[MAXN]; void addall( ) { rep( i , 2 , cnt ) G[par[i]].pb( i ); } ll S[MAXN] , k[MAXN] , b[MAXN]; int g[MAXN][20]; void dfs( int u ) { S[u] = len[u] - len[par[u]]; for( int v : G[u] ) { g[v][0] = u; rep( k , 1 , 18 ) if( g[g[v][k - 1]][k - 1] ) g[v][k] = g[g[v][k - 1]][k - 1]; else break; dfs( v ); S[u] += S[v]; } k[u] = -1 , b[u] = S[u] + len[par[u]] + 1; } int deg[MAXN] , A[MAXN] , cn; void wkr( ) { addall( ); dfs( 1 ); rep( i , 1 , cnt ) rep( k , 0 , 25 ) if( son[i][k] ) ++ deg[son[i][k]]; queue<int> Q; Q.push( 1 ); while( !Q.empty() ) { int u = Q.front() , v; Q.pop(); A[++ cn] = u; rep( k , 0 , 25 ) if( ( v = son[u][k] ) && !( --deg[v] ) ) Q.push( v ); } reverse( A + 1 , A + 1 + cn ); rep( i , 1 , cn ) { int u = A[i] , v; rep( t , 0 , 25 ) if( v = son[u][t] ) k[u] += k[v] , b[u] += b[v] + k[v]; } } int jump( int u , int l ) { per( k , 18 , 0 ) if( g[u][k] && l <= len[g[u][k]] ) u = g[u][k]; return u; } } S ;
int ps[MAXN];
void solve() { cin >> n >> q; scanf("%s",ch + 1); rep( i , 1 , n ) S.ins( ch[i] ) , ps[i] = S.las; S.wkr( ); rep( i , 1 , q ) { int l , r; scanf("%d%d",&l,&r); int u = S.jump( ps[r] , r - l + 1 ); printf("%lld\n",S.k[u] * ( r - l + 1 ) + S.b[u]); } }
signed main() {
solve(); }
|