后缀数组模板。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef __int64 int64;
typedef long long ll;
#define M 100005
#define N 1000005
#define max_inf 0x7f7f7f7f
#define min_inf 0x80808080
const int mod = 1e9 + 7;
int sa[M] , rank[M] , height[M];
int wa[M] , wb[M] , wv[M] , wd[M];
int cmp(int *r , int a , int b , int l)
{
return r[a] == r[b] && r[a+l] == r[b+l];
}
void da(int *r , int n , int m)
{
int i , j , p , *x = wa , *y = wb , *t;
for (i = 0 ; i < m ; i++)wd[i] = 0;
for (i = 0 ; i < n ; i++)wd[x[i]=r[i]]++;
for (i = 1 ; i < m ; i++)wd[i] += wd[i-1];
for (i = n-1 ; i >= 0 ; i--) sa[--wd[x[i]]] = i;
for (j = p = 1 ; p < n ; j *= 2 , m = p)
{
for (p = 0 , i = n-j ; i < n ; i++)y[p++] = i;
for (i = 0 ; i < n ; i++)if (sa[i] >= j)y[p++] = sa[i]-j;
for (i = 0 ; i < n ; i++)wv[i] = x[y[i]];
for (i = 0 ; i < m ; i++)wd[i] = 0;
for (i = 0 ; i < n ; i++)wd[wv[i]]++;
for (i = 1 ; i < m ; i++)wd[i] += wd[i-1];
for (i = n-1 ; i >= 0 ; i--)sa[--wd[wv[i]]] = y[i];
for (t = x , x = y , y = t , p = 1 , x[sa[0]] = 0 , i = 1 ; i < n ; i++)
x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++;
}
}
void calheight(int *r , int n)
{
int i , j , k = 0;
for (i = 1 ; i <= n ; i++) rank[sa[i]] = i;
for (i = 0 ; i < n ; height[rank[i++]] = k)
for (k?k--:0,j = sa[rank[i]-1] ; r[i+k] == r[j+k] ; k++);
}
char str[M];
int r[M];
int dp[M][20] , LOG[M];
void Init(int n)
{
int i , j , k;
for (i = 1 ; i <= n ; i++)dp[i][0] = height[i];
for (i = 1 ; i <= LOG[n] ; i++)
{
for (j = 1 ; j+(1<<i)-1 <= n ; j++)
{
dp[j][i] = min(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
}
}
}
int Query(int l , int r)
{
int k = LOG[r-l+1];
return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
int Judge(int k)
{
int ret = 0;
while (k)
{
ret++;
k /= 10;
}
return ret ? ret : 1;
}
int main()
{
int i;
for (LOG[0] = -1 , i = 1 ; i < M ; i++)LOG[i] = LOG[i>>1]+1;
while (~scanf("%s",str))
{
int len = strlen(str);
for (i = 0 ; i < len ; i++)r[i] = str[i]-'a'+1;
r[len] = 0;
da(r,len+1,28);
calheight(r,len);
Init(len);
int m;
scanf("%d",&m);
int px , py , nx , ny;
scanf("%d%d",&px,&py);
ll ans1 = 0 , ans2 = 0;
ans1 += py-px+1;
ans2 += py-px+3;
int temp;
while (--m)
{
scanf("%d%d",&nx,&ny);
if (px == nx)temp = min(py-px,ny-nx);
else
{
int l = rank[px] , r = rank[nx];
if (l > r)swap(l,r);
temp = Query(l+1,r);
temp = min(temp,min(py-px,ny-nx));
}
ans1 += ny-nx+1;
ans2 += ny-nx-temp+2+Judge(temp);
py = ny;
px = nx;
}
printf("%I64d %I64d\n",ans1,ans2);
}
return 0;
}