#include<stdio.h> #include<stdlib.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; #define MAXN 100010 struct suffix { int wa[MAXN],wb[MAXN],wv[MAXN],ws[MAXN],height[MAXN],rank[MAXN]; 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 *sa,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) ws[i]=0; for(i=0;i<n;i++) ws[x[i]=r[i]]++; for(i=1;i<m;i++) ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i; for(p=1,j=1;p<n;j<<=1,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<m;i++) ws[i]=0; for(i=0;i<n;i++) ws[wv[i]=x[y[i]]]++; for(i=1;i<m;i++) ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[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 get_height(int *r,int *sa,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++); } }a; int sa[MAXN],len=0,ch[MAXN]; int N,value[6*MAXN],minlen; char in[MAXN]; long long ans1,ans2; void build(int node,int left,int right) { if(left==right) { value[node]=a.height[left]; return; } int middle=(left+right)>>1; build(node<<1,left,middle); build(node<<1|1,middle+1,right); value[node]=value[node<<1]<value[node<<1|1]?value[node<<1]:value[node<<1|1]; } void getmin(int node,int left,int right,int L,int R) { if(right<L || R<left) return; if(L<=left && right<=R) { minlen=minlen<value[node]?minlen:value[node]; return; } int middle=(left+right)>>1; getmin(node<<1,left,middle,L,R); getmin(node<<1|1,middle+1,right,L,R); } int getdigit(int number) { int cnt=0; if(number==0) return 1; while(number>0) { cnt++; number/=10; } return cnt; } int main() { #ifndef ONLINE_JUDGE freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif while(scanf("%s",in)!=EOF) { memset(value,0,sizeof(value)); memset(ch,0,sizeof(ch)); len=strlen(in); for(int i=0;i<len;i++) ch[i]=in[i]-'a'+1; ch[len]=0; a.DA(ch,sa,len+1,27); a.get_height(ch,sa,len); build(1,1,len); scanf("%d",&N); ans1=N;ans2=2ll*N;//将空格和换行符的大小加上 int L,R; scanf("%d%d",&L,&R); ans1+=(long long)R-L;ans2+=(long long)R-L+1; for(int i=2;i<=N;i++) { int lastl=L,lastr=R,l,r; scanf("%d%d",&L,&R); l=a.rank[lastl];r=a.rank[L]; if(l>r) swap(l,r); minlen=MAXN; getmin(1,1,len,l+1,r); minlen=min(minlen,min(lastr-lastl,R-L)); } ans1+=(long long)R-L; ans2+=(long long)getdigit(minlen)+(long long)(R-L-minlen); } printf("%I64d %I64d\n",ans1,ans2); } return 0; }