Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 30544 | Accepted: 10208 |
Description
Many composers structure their music around a repeating &qout;theme&qout;, which, being a subsequence of an entire melody, is a sequence of integers in our representation. A subsequence of a melody is a theme if it:
- is at least five notes long
- appears (potentially transposed -- see below) again somewhere else in the piece of music
- is disjoint from (i.e., non-overlapping with) at least one of its other appearance(s)
Transposed means that a constant positive or negative value is added to every note value in the theme subsequence.
Given a melody, compute the length (number of notes) of the longest theme.
One second time limit for this problem's solutions!
Input
The last test case is followed by one zero.
Output
Sample Input
30 25 27 30 34 39 45 52 60 69 79 69 60 52 45 39 34 30 26 22 18 82 78 74 70 66 67 64 60 65 80 0
Sample Output
5
论文模板题,求出height后二分答案,在二分的时候按照mid把后缀数组进行分组,每组内的后缀最小公共前缀>=mid。只要有一组内的头位置最大值最小值相差>=mid,说明是存在长度为mid的不重叠子串。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define clr(x) memset(x,0,sizeof(x)) 6 #define clrmax(x) memset)x,0x3f3f3f3f,sizeof(x)) 7 using namespace std; 8 const int N=2e4+10; 9 int ranked[N],order[N],backet[N],s[N],sa[N],key1[N],key2[N],height[N]; 10 int n,m,l,r,mid,T,ans; 11 //两后缀比较大小 12 bool cmp(int *r,int a,int b,int len) 13 { 14 return r[a]==r[b] && r[a+len]==r[b+len]; 15 } 16 //求后缀数组sa,r为字符串,order代表按照第二关键字排序后的第一关键字的顺序,x[i]代表i的后缀的rank,y[i]代表第二关键字为i的头位置。order[i]代表按照第二关键字排序完rank为i的后缀对应的第一关键字对应的rank 17 void da(int *sa,int *r,int n,int m) 18 { 19 int i,j,p,*x=key1,*y=key2,*t; 20 //对长度为1的字符排序 21 for(i=0;i<m;i++) backet[i]=0; 22 for(i=0;i<n;i++) backet[x[i]=r[i]]++; 23 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 24 for(i=n-1;i>=0;i--) sa[--backet[x[i]]]=i; 25 for(j=1,p=1;p<n;j*=2,m=p) 26 { 27 //按第二关键字排序 28 for(p=0,i=n-j;i<n;i++) y[p++]=i; 29 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 30 //以第二关键字排序的结果按照第一关键字排序 31 for(i=0;i<n;i++) order[i]=x[y[i]]; 32 for(i=0;i<m;i++) backet[i]=0; 33 for(i=0;i<n;i++) backet[order[i]]++; 34 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 35 for(i=n-1;i>=0;i--) sa[--backet[order[i]]]=y[i]; 36 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) 37 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 38 } 39 return ; 40 } 41 //求height数组 42 void calheight(int *sa,int *r,int n) 43 { 44 int i,j,k=0; 45 //求出sa对应的rank 46 for(i=1;i<=n;i++) ranked[sa[i]]=i; 47 //按照h[i]去求height[i] 48 for(i=0;i<n;i++) 49 { 50 if(k) k--; 51 j=sa[ranked[i]-1]; 52 while(r[i+k]==r[j+k]) k++; 53 height[ranked[i]]=k; 54 } 55 return ; 56 } 57 int minn,minpos,maxpos,flag; 58 int main() 59 { 60 while(scanf("%d",&n)!=EOF && n) 61 { 62 for(int i=1;i<=n;i++) 63 { 64 scanf("%d",&s[i]); 65 } 66 for(int i=1;i<n;i++) 67 { 68 s[i]=s[i+1]-s[i]+100; 69 } 70 s[n]=1; 71 n--; 72 da(sa,s+1,n+1,200); 73 calheight(sa,s+1,n); 74 l=0; 75 r=n/2; 76 // for(int i=0;i<=n;i++) 77 // printf("%d ",sa[i]); 78 // printf(" "); 79 // for(int i=0;i<=n;i++) 80 // printf("%d ",ranked[i]); 81 // printf(" "); 82 // for(int i=0;i<=n;i++) 83 // printf("%d ",height[i]); 84 // printf(" "); 85 //二分答案求值 86 while(l<=r) 87 { 88 mid=(r+l)>>1; 89 minn=n; 90 minpos=maxpos=sa[1]; 91 flag=0; 92 for(int i=2;i<=n;i++) 93 { 94 if(height[i]<mid) 95 maxpos=minpos=sa[i]; 96 else 97 { 98 maxpos=max(maxpos,sa[i]); 99 minpos=min(minpos,sa[i]); 100 if(maxpos-minpos>=mid) 101 { 102 flag=1; 103 break; 104 } 105 } 106 } 107 if(flag) 108 ans=mid,l=mid+1; 109 else 110 r=mid-1; 111 } 112 if(ans<4) 113 printf("0 "); 114 else 115 printf("%d ",ans+1); 116 } 117 return 0; 118 }
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 16268 | Accepted: 7175 | |
Case Time Limit: 2000MS |
Description
Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can't predict the quality of milk from one day to the next, there are some regular patterns in the daily milk quality.
To perform a rigorous study, he has invented a complex classification scheme by which each milk sample is recorded as an integer between 0 and 1,000,000 inclusive, and has recorded data from a single cow over N (1 ≤ N ≤ 20,000) days. He wishes to find the longest pattern of samples which repeats identically at least K (2 ≤ K ≤ N) times. This may include overlapping patterns -- 1 2 3 2 3 2 3 1 repeats 2 3 2 3 twice, for example.
Help Farmer John by finding the longest repeating subsequence in the sequence of samples. It is guaranteed that at least one subsequence is repeated at least K times.
Input
Lines 2..N+1: N integers, one per line, the quality of the milk on day i appears on the ith line.
Output
Sample Input
8 2 1 2 3 2 3 2 3 1
Sample Output
4
依旧论文模板题,仍旧二分答案,满足的条件是区间内元素大于等于k。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define clr(x) memset(x,0,sizeof(x)) 6 #define clrmax(x) memset)x,0x3f3f3f3f,sizeof(x)) 7 using namespace std; 8 const int N=1e5+10; 9 int ranked[N],order[N],backet[N],s[N],sa[N],key1[N],key2[N],height[N]; 10 int n,m,ans,k; 11 int unrep[N]; 12 bool cmp(int *r,int a,int b,int len) 13 { 14 return r[a]==r[b] && r[a+len]==r[b+len]; 15 } 16 void da(int *sa,int *r,int n,int m) 17 { 18 int i,j,p,*x=key1,*y=key2,*t; 19 for(i=0;i<m;i++) backet[i]=0; 20 for(i=0;i<n;i++) backet[x[i]=r[i]]++; 21 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 22 for(i=n-1;i>=0;i--) sa[--backet[x[i]]]=i; 23 for(j=1,p=1;p<n;j*=2,m=p) 24 { 25 for(p=0,i=n-j;i<n;i++) y[p++]=i; 26 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 27 for(i=0;i<n;i++) order[i]=x[y[i]]; 28 for(i=0;i<m;i++) backet[i]=0; 29 for(i=0;i<n;i++) backet[order[i]]++; 30 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 31 for(i=n-1;i>=0;i--) sa[--backet[order[i]]]=y[i]; 32 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) 33 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 34 } 35 return ; 36 } 37 void calheight(int *sa,int *r,int n) 38 { 39 int i,j,k=0; 40 for(i=1;i<=n;i++) ranked[sa[i]]=i; 41 for(i=0;i<n;i++) 42 { 43 if(k) k--; 44 j=sa[ranked[i]-1]; 45 while(r[i+k]==r[j+k]) k++; 46 height[ranked[i]]=k; 47 } 48 return ; 49 } 50 bool check(int k,int mid,int n,int *heigiht) 51 { 52 int ct=1; 53 for(int i=2;i<=n;i++) 54 { 55 if(height[i]<mid) 56 { 57 ct=1; 58 } 59 else 60 { 61 if((++ct)>=k) 62 { 63 return 1; 64 } 65 } 66 } 67 return 0; 68 } 69 void bina(int &ans,int k,int *height,int n) 70 { 71 int l=ans=1,r=n,mid; 72 while(l<=r) 73 { 74 mid=(l+r)>>1; 75 if(check(k,mid,n,height)) 76 ans=mid,l=mid+1; 77 else 78 r=mid-1; 79 } 80 return ; 81 } 82 int main() 83 { 84 while(scanf("%d%d",&n,&k)!=EOF) 85 { 86 for(int i=1;i<=n;i++) 87 scanf("%d",&s[i]); 88 memcpy(unrep,s,sizeof(s)); 89 sort(unrep+1,unrep+n+1); 90 m=unique(unrep+1,unrep+n+1)-unrep-1; 91 for(int i=1;i<=n;i++) 92 s[i]=lower_bound(unrep+1,unrep+m+1,s[i])-unrep; 93 s[++n]=0; 94 da(sa,s+1,n,m+10); 95 n--; 96 calheight(sa,s+1,n); 97 bina(ans,k,height,n); 98 printf("%d ",ans); 99 } 100 return 0; 101 }
poj 2406
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 51609 | Accepted: 21523 |
Description
Input
Output
Sample Input
abcd aaaa ababab .
Sample Output
1 4 3
这题用KMP去匹配会更好一点。。但论文里要求了用后缀数组那就用吧~。
这题得用DC3不然时间不太够。然后求每个后缀和0后缀的最长公共前缀(lcp)。然后只要位置k的后缀和0后缀的lcp长度为n-k说明0~k-1这是一个整串的重复子串。我们只要找到最短的一个重复子串,那么就能使得求得的n最大了。
于是height处理完以后,求出各个后缀和0后缀的lcp,从小到大找符合要求的子串长度(n%k==0的长度k是合法的)。求这个lcp是O(1)的。整个算法是O(n)的(DC3的常数会比较大)。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #define clr(x) memset(x,0,sizeof(x)) 6 #define clr_1(x) memset(x,-1,sizeof(x)) 7 #define LL long long 8 #define mod 1000000007 9 #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) 10 #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x) - tb) * 3 + 2) 11 using namespace std; 12 const int N=3e6+10; 13 int wa[N],wb[N],backet[N],order[N],sa[N]; 14 int ranked[N],height[N],s[N],lcp[N],n; 15 char str[N]; 16 int c0(int *r,int a,int b) 17 { 18 return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2]; 19 } 20 int c12(int k,int *r,int a,int b) 21 { 22 if(k==2) return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1); 23 else return r[a]<r[b]||r[a]==r[b]&&order[a+1]<order[b+1]; 24 } 25 void sorted(int *r,int *a,int *b,int n,int m) 26 { 27 int i; 28 for(i=0;i<n;i++) order[i]=r[a[i]]; 29 for(i=0;i<m;i++) backet[i]=0; 30 for(i=0;i<n;i++) backet[order[i]]++; 31 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 32 for(i=n-1;i>=0;i--) b[--backet[order[i]]]=a[i]; 33 return; 34 } 35 void dc3(int *r,int *sa,int n,int m) 36 { 37 int i,j,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p; 38 int *rn=r+n; 39 r[n]=r[n+1]=0; 40 for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i; 41 sorted(r+2,wa,wb,tbc,m); 42 sorted(r+1,wb,wa,tbc,m); 43 sorted(r,wa,wb,tbc,m); 44 for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++) 45 rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++; 46 if(p<tbc) dc3(rn,san,tbc,p); 47 else for(i=0;i<tbc;i++) san[rn[i]]=i; 48 for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3; 49 if(n%3==1) wb[ta++]=n-1; 50 sorted(r,wb,wa,ta,m); 51 for(i=0;i<tbc;i++) order[wb[i]=G(san[i])]=i; 52 for(i=0,j=0,p=0;i<ta && j<tbc;p++) 53 sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++]; 54 for(;i<ta;p++) sa[p]=wa[i++]; 55 for(;j<tbc;p++) sa[p]=wb[j++]; 56 return; 57 } 58 void calheight(int *r, int *sa, int n) { 59 int i, j, k = 0; 60 for (i = 1; i <= n; i++) ranked[sa[i]] = i; 61 for (i = 0; i < n; height[ranked[i++]] = k) 62 for (k ? k-- : 0, j = sa[ranked[i] - 1]; r[i + k] == r[j + k]; k++); 63 return ; 64 } 65 66 int len,m,ans; 67 int main() 68 { 69 while(scanf("%s",str) && str[0]!='.') 70 { 71 len=strlen(str); 72 for(int i=0;i<len;i++) 73 s[i]=str[i]-'a'+1; 74 s[len]=0; 75 dc3(s,sa,len+1,30); 76 calheight(s,sa,len); 77 m=ranked[0]; 78 lcp[0]=len; 79 for( int i=2;i<=m;i++) 80 lcp[sa[i-1]]=min(height[i],lcp[sa[i]]); 81 for(int i=m+1;i<=len;i++) 82 lcp[sa[i]]=min(height[i],lcp[sa[i-1]]); 83 for(int i=1;i<=len;i++) 84 if(len%i==0) 85 { 86 if(lcp[i]==len-i) 87 { 88 ans=len/i; 89 break; 90 } 91 } 92 printf("%d ",ans); 93 } 94 }
SPOJ SUBST1
SUBST1 - New Distinct Substrings
Given a string, we need to find the total number of its distinct substrings.
Input
T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000
Output
For each test case output one number saying the number of distinct substrings.
Example
Input: 2 CCCCC ABABA Output: 5 9
论文题,求出height后height0和height(n+1)都作为0,然后求sa上每串和他sa位置相邻的两串中最长的前缀(height),则是这一串里最长(长度为h)的相同子串,把后缀长度减去该子串长度就是该串贡献的不同的子串的个数(即长度为(h+1)~n-sa[i]).
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define clr(x) memset(x,0,sizeof(x)) 6 #define clrmax(x) memset)x,0x3f3f3f3f,sizeof(x)) 7 using namespace std; 8 const int N=1e5+10; 9 int ranked[N],order[N],backet[N],sa[N],key1[N],key2[N],height[N]; 10 char s[N]; 11 int n,m,ans,k; 12 int unrep[N]; 13 bool cmp(int *r,int a,int b,int len) 14 { 15 return r[a]==r[b] && r[a+len]==r[b+len]; 16 } 17 void da(int *sa,char *r,int n,int m) 18 { 19 int i,j,p,*x=key1,*y=key2,*t; 20 for(i=0;i<m;i++) backet[i]=0; 21 for(i=0;i<n;i++) backet[x[i]=r[i]]++; 22 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 23 for(i=n-1;i>=0;i--) sa[--backet[x[i]]]=i; 24 for(j=1,p=1;p<n;j*=2,m=p) 25 { 26 for(p=0,i=n-j;i<n;i++) y[p++]=i; 27 for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; 28 for(i=0;i<n;i++) order[i]=x[y[i]]; 29 for(i=0;i<m;i++) backet[i]=0; 30 for(i=0;i<n;i++) backet[order[i]]++; 31 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 32 for(i=n-1;i>=0;i--) sa[--backet[order[i]]]=y[i]; 33 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) 34 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 35 } 36 return ; 37 } 38 void calheight(int *sa,char *r,int n) 39 { 40 int i,j,k=0; 41 for(i=1;i<=n;i++) ranked[sa[i]]=i; 42 for(i=0;i<n;i++) 43 { 44 if(k) k--; 45 j=sa[ranked[i]-1]; 46 while(r[i+k]==r[j+k]) k++; 47 height[ranked[i]]=k; 48 } 49 return ; 50 } 51 int main() 52 { 53 int T; 54 scanf("%d",&T); 55 while(T--) 56 { 57 scanf("%s",s); 58 n=strlen(s); 59 n++; 60 da(sa,s,n,200); 61 n--; 62 calheight(sa,s,n); 63 height[n+1]=height[1]=0; 64 ans=0; 65 for(int i=1;i<=n;i++) 66 { 67 ans+=n-sa[i]-height[i]; 68 } 69 printf("%d ",ans); 70 } 71 return 0; 72 }
SPOJ - REPEATS
REPEATS - Repeats
A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed string t with length l>=1. For example, the string
s = abaabaabaaba
is a (4,3)-repeat with t = aba as its seed string. That is, the seed string t is 3 characters long, and the whole string s is obtained by repeating t 4 times.
Write a program for the following task: Your program is given a long string u consisting of characters ‘a’ and/or ‘b’ as input. Your program must find some (k,l)-repeat that occurs as substring within u with k as large as possible. For example, the input string
u = babbabaabaabaabab
contains the underlined (4,3)-repeat s starting at position 5. Since u contains no other contiguous substring with more than 4 repeats, your program must output the maximum k.
Input
In the first line of the input contains H- the number of test cases (H <= 20). H test cases follow. First line of each test cases is n - length of the input string (n <= 50000), The next n lines contain the input string, one character (either ‘a’ or ‘b’) per line, in order.
Output
For each test cases, you should write exactly one interger k in a line - the repeat count that is maximized.
Example
Input: 1 17 b a b b a b a a b a a b a a b a b Output: 4
有两种方法。基础是罗穗骞《后缀数组——处理字符串的有力工具》写的:
然后第一个就是求一遍后缀数组和height,然后写st表来快速求两后缀的最长公共前缀。然后用这个lcp[i][i+l]的长度定位该重复子串头,当前位置为i,那么头位置为tj=i-lcp[i][i+l]%i,然后再求一遍lcp[tj][tj+l],那lcp[tj][tj+l]/l即为其重复次数。
第二种会麻烦点,时间也久一点求后缀数组的lcp,把该字符串倒过来,也求其后缀数组的lcp,相当于求其前缀数组的lcs。然后每次就将i和i+l俩位置的后缀的lcp以及i-1,i+l-1俩位置前缀的lcs相加,除以l+1,即为重复次数。
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define clr_1(x) memset(x,-1,sizeof(x)) 4 #define LL long long 5 #define mod 1000000007 6 #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) 7 #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x) - tb) * 3 + 2) 8 using namespace std; 9 const int N=1e6+10; 10 const int M=1e5+10; 11 int wa[N],wb[N],backet[N],order[N],sal[N]; 12 int rankl[N],heightl[N],sl[N],n; 13 typedef vector<int> vec; 14 typedef vector<vec> stable; 15 stable stl(M,vec(20)); 16 int c0(int *r,int a,int b) 17 { 18 return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2]; 19 } 20 int c12(int k,int *r,int a,int b) 21 { 22 if(k==2) return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1); 23 else return r[a]<r[b]||r[a]==r[b]&&order[a+1]<order[b+1]; 24 } 25 void sorted(int *r,int *a,int *b,int n,int m) 26 { 27 int i; 28 for(i=0;i<n;i++) order[i]=r[a[i]]; 29 for(i=0;i<m;i++) backet[i]=0; 30 for(i=0;i<n;i++) backet[order[i]]++; 31 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 32 for(i=n-1;i>=0;i--) b[--backet[order[i]]]=a[i]; 33 return; 34 } 35 void dc3(int *r,int *sa,int n,int m) 36 { 37 int i,j,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p; 38 int *rn=r+n; 39 r[n]=r[n+1]=0; 40 for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i; 41 sorted(r+2,wa,wb,tbc,m); 42 sorted(r+1,wb,wa,tbc,m); 43 sorted(r,wa,wb,tbc,m); 44 for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++) 45 rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++; 46 if(p<tbc) dc3(rn,san,tbc,p); 47 else for(i=0;i<tbc;i++) san[rn[i]]=i; 48 for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3; 49 if(n%3==1) wb[ta++]=n-1; 50 sorted(r,wb,wa,ta,m); 51 for(i=0;i<tbc;i++) order[wb[i]=G(san[i])]=i; 52 for(i=0,j=0,p=0;i<ta && j<tbc;p++) 53 sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++]; 54 for(;i<ta;p++) sa[p]=wa[i++]; 55 for(;j<tbc;p++) sa[p]=wb[j++]; 56 return; 57 } 58 void calheight(int *r, int *sa, int n,int *height,int *ranked) { 59 int i, j, k = 0; 60 for (i = 1; i <= n; i++) ranked[sa[i]] = i; 61 for (i = 0; i < n; height[ranked[i++]] = k) 62 for (k ? k-- : 0, j = sa[ranked[i] - 1]; r[i + k] == r[j + k]; k++); 63 return ; 64 } 65 void dealst(int *height,stable &st,int n,int *sa) 66 { 67 int t=0,k,divk; 68 for(int i=1;i<n;i++) 69 st[i][1]=height[i+1]; 70 for(k=4,t=2,divk=2;k<=n;k<<=1,divk<<=1,t++) 71 for(int i=1;i<=n-k+1;i++) 72 st[i][t]=min(min(st[i][t-1],st[i+divk][t-1]),height[i+divk]); 73 return ; 74 } 75 int query(int u,int v,stable &st,int *ranked) 76 { 77 u=ranked[u]; 78 v=ranked[v]; 79 if(u>v) swap(u,v); 80 int p=v-u+1,k=0; 81 while(p) 82 { 83 p>>=1; 84 k++; 85 } 86 return min(st[u][k-1],st[v-(1<<k-1)+1][k-1]); 87 } 88 int m,ans,maxn,tj,d; 89 int main() 90 { 91 int T,n,m; 92 char c; 93 scanf("%d",&T); 94 while(T--) 95 { 96 scanf("%d",&n); 97 for(int i=0;i<n;i++) 98 { 99 scanf(" %c",&c); 100 sl[i]=c-'a'+1; 101 } 102 if(n==0) 103 { 104 printf("0 "); 105 continue; 106 } 107 sl[n++]=0; 108 dc3(sl,sal,n,30); 109 n--; 110 calheight(sl,sal,n,heightl,rankl); 111 dealst(heightl,stl,n,sal); 112 maxn=0; 113 for(int l=1;l<=n/2;l++) 114 { 115 for(int j=0;j<n-l;j+=l) 116 { 117 d=query(j,j+l,stl,rankl); 118 ans=d/l; 119 tj=j-(l-d%l); 120 if(tj>=0) 121 { 122 if(query(tj,tj+l,stl,rankl)>=l-d%l) 123 ans++; 124 } 125 if(maxn<ans) 126 maxn=ans; 127 } 128 } 129 printf("%d ",maxn+1); 130 } 131 return 0; 132 }
1 #include<bits/stdc++.h> 2 #define clr(x) memset(x,0,sizeof(x)) 3 #define clr_1(x) memset(x,-1,sizeof(x)) 4 #define LL long long 5 #define mod 1000000007 6 #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) 7 #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x) - tb) * 3 + 2) 8 using namespace std; 9 const int N=1e6+10; 10 const int M=1e5+10; 11 int wa[N],wb[N],backet[N],order[N],sap[N],sal[N]; 12 int rankp[N],heightp[N],rankl[N],heightl[N],sp[N],sl[N],n; 13 typedef vector<int> vec; 14 typedef vector<vec> stable; 15 stable stp(M,vec(20)),stl(M,vec(20)); 16 int c0(int *r,int a,int b) 17 { 18 return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2]; 19 } 20 int c12(int k,int *r,int a,int b) 21 { 22 if(k==2) return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1); 23 else return r[a]<r[b]||r[a]==r[b]&&order[a+1]<order[b+1]; 24 } 25 void sorted(int *r,int *a,int *b,int n,int m) 26 { 27 int i; 28 for(i=0;i<n;i++) order[i]=r[a[i]]; 29 for(i=0;i<m;i++) backet[i]=0; 30 for(i=0;i<n;i++) backet[order[i]]++; 31 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 32 for(i=n-1;i>=0;i--) b[--backet[order[i]]]=a[i]; 33 return; 34 } 35 void dc3(int *r,int *sa,int n,int m) 36 { 37 int i,j,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p; 38 int *rn=r+n; 39 r[n]=r[n+1]=0; 40 for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i; 41 sorted(r+2,wa,wb,tbc,m); 42 sorted(r+1,wb,wa,tbc,m); 43 sorted(r,wa,wb,tbc,m); 44 for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++) 45 rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++; 46 if(p<tbc) dc3(rn,san,tbc,p); 47 else for(i=0;i<tbc;i++) san[rn[i]]=i; 48 for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3; 49 if(n%3==1) wb[ta++]=n-1; 50 sorted(r,wb,wa,ta,m); 51 for(i=0;i<tbc;i++) order[wb[i]=G(san[i])]=i; 52 for(i=0,j=0,p=0;i<ta && j<tbc;p++) 53 sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++]; 54 for(;i<ta;p++) sa[p]=wa[i++]; 55 for(;j<tbc;p++) sa[p]=wb[j++]; 56 return; 57 } 58 void calheight(int *r, int *sa, int n,int *height,int *ranked) { 59 int i, j, k = 0; 60 for (i = 1; i <= n; i++) ranked[sa[i]] = i; 61 for (i = 0; i < n; height[ranked[i++]] = k) 62 for (k ? k-- : 0, j = sa[ranked[i] - 1]; r[i + k] == r[j + k]; k++); 63 return ; 64 } 65 void dealst(int *height,stable &st,int n,int *sa) 66 { 67 int t=0,k,divk; 68 for(int i=1;i<n;i++) 69 st[i][1]=height[i+1]; 70 for(k=4,t=2,divk=2;k<=n;k<<=1,divk<<=1,t++) 71 for(int i=1;i<=n-k+1;i++) 72 st[i][t]=min(min(st[i][t-1],st[i+divk][t-1]),height[i+divk]); 73 return ; 74 } 75 int query(int u,int v,stable &st,int *ranked) 76 { 77 u=ranked[u]; 78 v=ranked[v]; 79 if(u>v) swap(u,v); 80 int p=v-u+1,k=0; 81 while(p) 82 { 83 p>>=1; 84 k++; 85 } 86 return min(st[u][k-1],st[v-(1<<k-1)+1][k-1]); 87 } 88 int len,m,ans,maxn; 89 int main() 90 { 91 int T,n,m; 92 char c; 93 scanf("%d",&T); 94 while(T--) 95 { 96 scanf("%d",&n); 97 for(int i=0;i<n;i++) 98 { 99 scanf(" %c",&c); 100 sp[n-i-1]=sl[i]=c-'a'+1; 101 } 102 if(n==0) 103 { 104 printf("0 "); 105 continue; 106 } 107 sp[n]=0; 108 sl[n++]=0; 109 dc3(sp,sap,n,30); 110 dc3(sl,sal,n,30); 111 n--; 112 calheight(sp,sap,n,heightp,rankp); 113 calheight(sl,sal,n,heightl,rankl); 114 dealst(heightp,stp,n,sap); 115 dealst(heightl,stl,n,sal); 116 maxn=1; 117 for(int l=1;l<=n/2;l++) 118 { 119 for(int j=0;j<n-l;j+=l) 120 { 121 ans=query(j,j+l,stl,rankl)+query(n-j,n-j-l,stp,rankp); 122 ans=ans/l+1; 123 if(ans>maxn) 124 maxn=ans; 125 126 } 127 } 128 printf("%d ",maxn); 129 } 130 return 0; 131 }
poj 3693
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10540 | Accepted: 3255 |
Description
The repetition number of a string is defined as the maximum number R such that the string can be partitioned into R same consecutive substrings. For example, the repetition number of "ababab" is 3 and "ababa" is 1.
Given a string containing lowercase letters, you are to find a substring of it with maximum repetition number.
Input
The input consists of multiple test cases. Each test case contains exactly one line, which
gives a non-empty string consisting of lowercase letters. The length of the string will not be greater than 100,000.
The last test case is followed by a line containing a '#'.
Output
For each test case, print a line containing the test case number( beginning with 1) followed by the substring of maximum repetition number. If there are multiple substrings of maximum repetition number, print the lexicographically smallest one.
Sample Input
ccabababc daabbccaa #
Sample Output
Case 1: ababab Case 2: aa
因为内存开大了所以超时了????反正我开100w的数组他不提示mle而是tle。。我开小点就过了。
跟上题一样,由于每次都要查询符合条件位置及其前l-1个里面字典序是否最小,时间复杂度接近o(n*n),所以最好加入若干优化。第一个就是str[j]==str[j+l]弱两个位置字符不同,那就没有最长公共前缀了,可以continue。第二个则是查找到有效的位置j后,那么下次查找的位置则是其最长公共前缀lcp+j这个位置左右。因为是隔l个检查符合,所以下次检查j+lcp/l*l-l及j+l两者靠后的那个。这个不知道为什么wa了所以没写了。。。如果有极端数据10w个a这样的,估计要跑十几秒。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<vector> 6 #define clr(x) memset(x,0,sizeof(x)) 7 #define clr_1(x) memset(x,-1,sizeof(x)) 8 #define LL long long 9 #define mod 1000000007 10 #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) 11 #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x) - tb) * 3 + 2) 12 using namespace std; 13 const int N=5e5+10; 14 int wa[N],wb[N],backet[N],order[N],sa[N]; 15 int ranked[N],height[N],s[N],n; 16 typedef vector<int> vec; 17 typedef vector<vec> stable; 18 int st[N][30]; 19 inline int min(int a,int b) 20 { 21 return a<b?a:b; 22 } 23 inline int max(int a,int b) 24 { 25 return a>b?a:b; 26 } 27 int c0(int *r,int a,int b) 28 { 29 return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2]; 30 } 31 int c12(int k,int *r,int a,int b) 32 { 33 if(k==2) return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1); 34 else return r[a]<r[b]||r[a]==r[b]&&order[a+1]<order[b+1]; 35 } 36 void sorted(int *r,int *a,int *b,int n,int m) 37 { 38 int i; 39 for(i=0;i<n;i++) order[i]=r[a[i]]; 40 for(i=0;i<m;i++) backet[i]=0; 41 for(i=0;i<n;i++) backet[order[i]]++; 42 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 43 for(i=n-1;i>=0;i--) b[--backet[order[i]]]=a[i]; 44 return; 45 } 46 void dc3(int *r,int *sa,int n,int m) 47 { 48 int i,j,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p; 49 int *rn=r+n; 50 r[n]=r[n+1]=0; 51 for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i; 52 sorted(r+2,wa,wb,tbc,m); 53 sorted(r+1,wb,wa,tbc,m); 54 sorted(r,wa,wb,tbc,m); 55 for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++) 56 rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++; 57 if(p<tbc) dc3(rn,san,tbc,p); 58 else for(i=0;i<tbc;i++) san[rn[i]]=i; 59 for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3; 60 if(n%3==1) wb[ta++]=n-1; 61 sorted(r,wb,wa,ta,m); 62 for(i=0;i<tbc;i++) order[wb[i]=G(san[i])]=i; 63 for(i=0,j=0,p=0;i<ta && j<tbc;p++) 64 sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++]; 65 for(;i<ta;p++) sa[p]=wa[i++]; 66 for(;j<tbc;p++) sa[p]=wb[j++]; 67 return; 68 } 69 void calheight(int *r, int *sa, int n) { 70 int i, j, k = 0; 71 for (i = 1; i <= n; i++) ranked[sa[i]] = i; 72 for (i = 0; i < n; height[ranked[i++]] = k) 73 for (k ? k-- : 0, j = sa[ranked[i] - 1]; r[i + k] == r[j + k]; k++); 74 height[1]=0; 75 return ; 76 } 77 void dealst(int n,int *sa) 78 { 79 int t=0,k,divk; 80 for(int i=1;i<n;i++) 81 st[i][1]=height[i+1]; 82 for(k=4,t=2,divk=2;k<=n;k<<=1,divk<<=1,t++) 83 for(int i=1;i<=n-k+1;i++) 84 st[i][t]=min(min(st[i][t-1],st[i+divk][t-1]),height[i+divk]); 85 return ; 86 } 87 int query(int u,int v) 88 { 89 u=ranked[u]; 90 v=ranked[v]; 91 if(u>v) swap(u,v); 92 int p=v-u+1,k=0; 93 while(p) 94 { 95 p>>=1; 96 k++; 97 } 98 return min(st[u][k-1],st[v-(1<<k-1)+1][k-1]); 99 } 100 int m,ans,maxn,lt,pos,len,now,kase,flag; 101 char str[N]; 102 int main() 103 { 104 int T=0; 105 while(++T) 106 { 107 scanf("%s",str); 108 if(str[0]=='#') break; 109 printf("Case %d: ",T); 110 n=strlen(str); 111 for(int i=0;i<n;i++) 112 s[i]=str[i]-'a'+1; 113 s[n++]=0; 114 dc3(s,sa,n,30); 115 n--; 116 calheight(s,sa,n); 117 dealst(n,sa); 118 maxn=1; 119 pos=0; 120 len=n; 121 for(int l=1;l<=n/2;l++) 122 { 123 for(int j=0;j<n-l;j+=l) 124 { 125 if(str[j]!=str[j+l]) continue; 126 ans=query(j,j+l); 127 for(int i=0;i<l;i++) 128 if(j-i<0 || str[j-i]!=str[j-i+l]) break; 129 else 130 { 131 now=(ans+i)/l+1; 132 if((now>maxn) || (now==maxn && ranked[j-i]<ranked[pos])) 133 { 134 maxn=now; 135 pos=j-i; 136 len=l; 137 } 138 } 139 } 140 } 141 if(maxn==1) printf("%c ",str[sa[1]]); 142 else 143 { 144 m=pos+len*maxn; 145 for(int i=pos;i<m;i++) 146 printf("%c",str[i]); 147 printf(" "); 148 } 149 } 150 return 0; 151 }
POJ 2774
Time Limit: 4000MS | Memory Limit: 131072K | |
Total Submissions: 31753 | Accepted: 12810 | |
Case Time Limit: 1000MS |
Description
The little cat lives in an unrich family, so he frequently comes to the mobile service center, to check how much money he has spent on SMS. Yesterday, the computer of service center was broken, and printed two very long messages. The brilliant little cat soon found out:
1. All characters in messages are lowercase Latin letters, without punctuations and spaces.
2. All SMS has been appended to each other – (i+1)-th SMS comes directly after the i-th one – that is why those two messages are quite long.
3. His own SMS has been appended together, but possibly a great many redundancy characters appear leftwards and rightwards due to the broken computer.
E.g: if his SMS is “motheriloveyou”, either long message printed by that machine, would possibly be one of “hahamotheriloveyou”, “motheriloveyoureally”, “motheriloveyouornot”, “bbbmotheriloveyouaaa”, etc.
4. For these broken issues, the little cat has printed his original text twice (so there appears two very long messages). Even though the original text remains the same in two printed messages, the redundancy characters on both sides would be possibly different.
You are given those two very long messages, and you have to output the length of the longest possible original text written by the little cat.
Background:
The SMS in Byterland mobile service are charging in dollars-per-byte. That is why the little cat is worrying about how long could the longest original text be.
Why ask you to write a program? There are four resions:
1. The little cat is so busy these days with physics lessons;
2. The little cat wants to keep what he said to his mother seceret;
3. POJ is such a great Online Judge;
4. The little cat wants to earn some money from POJ, and try to persuade his mother to see the doctor :(
Input
Output
Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit yeaphowmuchiloveyoumydearmother
Sample Output
27
emmm,水题把,把两串之间夹一个从未出现的最小数字,然后连起来,求其height。答案就是sa[i-1],sa[i]分属不同两串的最大的height。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<vector> 6 #define clr(x) memset(x,0,sizeof(x)) 7 #define clr_1(x) memset(x,-1,sizeof(x)) 8 #define LL long long 9 #define mod 1000000007 10 #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) 11 #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x) - tb) * 3 + 2) 12 using namespace std; 13 const int N=6e5+10; 14 const int M=1e5+10; 15 int wa[N],wb[N],backet[N],order[N],sa[N]; 16 int ranked[2*M],height[2*M],s[N],n; 17 inline int min(int a,int b) 18 { 19 return a<b?a:b; 20 } 21 inline int max(int a,int b) 22 { 23 return a>b?a:b; 24 } 25 int c0(int *r,int a,int b) 26 { 27 return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2]; 28 } 29 int c12(int k,int *r,int a,int b) 30 { 31 if(k==2) return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1); 32 else return r[a]<r[b]||r[a]==r[b]&&order[a+1]<order[b+1]; 33 } 34 void sorted(int *r,int *a,int *b,int n,int m) 35 { 36 int i; 37 for(i=0;i<n;i++) order[i]=r[a[i]]; 38 for(i=0;i<m;i++) backet[i]=0; 39 for(i=0;i<n;i++) backet[order[i]]++; 40 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 41 for(i=n-1;i>=0;i--) b[--backet[order[i]]]=a[i]; 42 return; 43 } 44 void dc3(int *r,int *sa,int n,int m) 45 { 46 int i,j,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p; 47 int *rn=r+n; 48 r[n]=r[n+1]=0; 49 for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i; 50 sorted(r+2,wa,wb,tbc,m); 51 sorted(r+1,wb,wa,tbc,m); 52 sorted(r,wa,wb,tbc,m); 53 for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++) 54 rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++; 55 if(p<tbc) dc3(rn,san,tbc,p); 56 else for(i=0;i<tbc;i++) san[rn[i]]=i; 57 for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3; 58 if(n%3==1) wb[ta++]=n-1; 59 sorted(r,wb,wa,ta,m); 60 for(i=0;i<tbc;i++) order[wb[i]=G(san[i])]=i; 61 for(i=0,j=0,p=0;i<ta && j<tbc;p++) 62 sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++]; 63 for(;i<ta;p++) sa[p]=wa[i++]; 64 for(;j<tbc;p++) sa[p]=wb[j++]; 65 return; 66 } 67 void calheight(int *r, int *sa, int n) { 68 int i, j, k = 0; 69 for (i = 1; i <= n; i++) ranked[sa[i]] = i; 70 for (i = 0; i < n; height[ranked[i++]] = k) 71 for (k ? k-- : 0, j = sa[ranked[i] - 1]; r[i + k] == r[j + k]; k++); 72 return ; 73 } 74 int m,ans,maxn,lt,pos,len,now,kase,flag; 75 char str1[M],str2[M]; 76 int main() 77 { 78 while(scanf("%s%s",str1,str2)!=EOF) 79 { 80 n=strlen(str1); 81 for(int i=0;i<n;i++) 82 s[i]=str1[i]-'a'+2; 83 s[n++]=1; 84 m=strlen(str2); 85 for(int i=n;i<n+m;i++) 86 s[i]=str2[i-n]-'a'+2; 87 n+=m; 88 m=strlen(str1); 89 s[n++]=0; 90 dc3(s,sa,n,30); 91 n--; 92 maxn=0; 93 calheight(s,sa,n); 94 for(int i=2;i<=n;i++) 95 if(height[i]>maxn) 96 { 97 if(sa[i-1]<m && sa[i]>m) 98 maxn=height[i]; 99 if(sa[i-1]>m && sa[i]<m) 100 maxn=height[i]; 101 } 102 printf("%d ",maxn); 103 } 104 return 0; 105 }
poj 3415
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 11380 | Accepted: 3761 |
Description
A substring of a string T is defined as:
Given two strings A, B and one integer K, we define S, a set of triples (i, j, k):
You are to give the value of |S| for specific A, B and K.
Input
The input file contains several blocks of data. For each block, the first line contains one integer K, followed by two lines containing strings A and B, respectively. The input file is ended by K=0.
1 ≤ |A|, |B| ≤ 105
1 ≤ K ≤ min{|A|, |B|}
Characters of A and B are all Latin letters.
Output
For each case, output an integer |S|.
Sample Input
2 aababaa abaabaa 1 xx xx 0
Sample Output
22 5
求两串中重复子串(位置不一样的相同子串是不同的)的长度大于k的重复子串个数。
把两串中间隔一个最小的数字接在一起后,那么这题就变成了height分组问题了--height按照最小为k区分组。按照sa的顺序到i以后,我们算出该分组前面的每个sa所对应的后缀和该点的后缀的最长公共前缀长度h,那么对答案贡献就是(h-k+1)。
可以用前缀和和单调栈快速近似O(1)求出。
具体做法是做个单调递增栈,即求最小值的单调递增栈。每个栈元素k(k代表他是栈底向上第k个元素)包括他的height值和height值的位置pos-1(sa位置),即他的位置值kpos=pos-1。每到达一个新位置(sa位置,后同)i,他都对应一个单调栈。栈里每个元素对代表什么呢?它代表某个位置到当前位置i的height最小值,即某个字符串位置的后缀和当前位置的后缀的最长公共前缀,这样的位置是对应在sa上是一段的,不妨称为最小值段。假如这个元素是栈底向上第k个元素,那他代表的最小值段是第k-1个元素的(k-1)pos+1,到当前元素k的kpos,这一段里面的后缀和当前位置i的最长公共前缀为height[k]。
这样就先是把时间复杂度减少了一部分。但不可能每次都遍历一遍栈。我们多增加一个数组ans,保存从分组最前位置到当前栈内元素位置kpos的串总数(这样的一个段由几个最小值段组成)。因为栈内元素的ans一旦确定即使i改变也是不会改变的(想想为什么),因此每次确定了i的单调栈,就能从top前一个元素的ans递推出top的ans。这样访问每个点都是O(1)的。把top的ans加入答案即可。当然由于是两个串,你得分a串和b串。每次都得递推a串和b串在该位置上的ansa,ansb。而求每个位置属于a串的前缀和属于b串的前缀,是为了快速求出两个相邻位置栈内元素之间a串和b串后缀的数量。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<vector> 6 #define clr(x) memset(x,0,sizeof(x)) 7 #define clr_1(x) memset(x,-1,sizeof(x)) 8 #define LL long long 9 #define mod 1000000007 10 #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) 11 #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x) - tb) * 3 + 2) 12 using namespace std; 13 const int N=1e6+10; 14 const int M=2e5+10; 15 int wa[N],wb[N],backet[N],order[N],sa[N]; 16 int ranked[2*M],height[2*M],s[N],n,stack[2*M],pos[2*M],top,suma[2*M],sumb[2*M]; 17 LL ansa[2*M],ansb[2*M]; 18 inline int min(int a,int b) 19 { 20 return a<b?a:b; 21 } 22 inline int max(int a,int b) 23 { 24 return a>b?a:b; 25 } 26 int c0(int *r,int a,int b) 27 { 28 return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2]; 29 } 30 int c12(int k,int *r,int a,int b) 31 { 32 if(k==2) return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1); 33 else return r[a]<r[b]||r[a]==r[b]&&order[a+1]<order[b+1]; 34 } 35 void sorted(int *r,int *a,int *b,int n,int m) 36 { 37 int i; 38 for(i=0;i<n;i++) order[i]=r[a[i]]; 39 for(i=0;i<m;i++) backet[i]=0; 40 for(i=0;i<n;i++) backet[order[i]]++; 41 for(i=1;i<m;i++) backet[i]+=backet[i-1]; 42 for(i=n-1;i>=0;i--) b[--backet[order[i]]]=a[i]; 43 return; 44 } 45 void dc3(int *r,int *sa,int n,int m) 46 { 47 int i,j,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p; 48 int *rn=r+n; 49 r[n]=r[n+1]=0; 50 for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i; 51 sorted(r+2,wa,wb,tbc,m); 52 sorted(r+1,wb,wa,tbc,m); 53 sorted(r,wa,wb,tbc,m); 54 for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++) 55 rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++; 56 if(p<tbc) dc3(rn,san,tbc,p); 57 else for(i=0;i<tbc;i++) san[rn[i]]=i; 58 for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3; 59 if(n%3==1) wb[ta++]=n-1; 60 sorted(r,wb,wa,ta,m); 61 for(i=0;i<tbc;i++) order[wb[i]=G(san[i])]=i; 62 for(i=0,j=0,p=0;i<ta && j<tbc;p++) 63 sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++]; 64 for(;i<ta;p++) sa[p]=wa[i++]; 65 for(;j<tbc;p++) sa[p]=wb[j++]; 66 return; 67 } 68 void calheight(int *r, int *sa, int n) { 69 int i, j, k = 0; 70 for (i = 1; i <= n; i++) ranked[sa[i]] = i; 71 for (i = 0; i < n; height[ranked[i++]] = k) 72 for (k ? k-- : 0, j = sa[ranked[i] - 1]; r[i + k] == r[j + k]; k++); 73 return ; 74 } 75 int m,maxn,k,cta,ctb,minn; 76 LL ans; 77 char str1[M],str2[M]; 78 int main() 79 { 80 while(scanf("%d",&k)!=EOF && k!=0) 81 { 82 scanf("%s%s",str1,str2); 83 n=strlen(str1); 84 for(int i=0;i<n;i++) 85 s[i]=str1[i]+2; 86 s[n++]=1; 87 m=strlen(str2); 88 for(int i=n;i<n+m;i++) 89 s[i]=str2[i-n]+2; 90 n+=m; 91 m=strlen(str1); 92 s[n++]=0; 93 dc3(s,sa,n,200); 94 n--; 95 calheight(s,sa,n); 96 suma[0]=sumb[0]=suma[1]=sumb[1]=0; 97 for(int i=2;i<=n;i++) 98 if(sa[i]>m) 99 { 100 sumb[i]=sumb[i-1]+1; 101 suma[i]=suma[i-1]; 102 } 103 else 104 { 105 sumb[i]=sumb[i-1]; 106 suma[i]=suma[i-1]+1; 107 } 108 ans=0; 109 top=0; 110 pos[0]=1; 111 ansa[0]=0; 112 ansb[0]=0; 113 for(int i=3;i<=n;i++) 114 { 115 if(height[i]<k) 116 { 117 top=0; 118 pos[0]=i-1; 119 } 120 else 121 { 122 while(top>0 && stack[top]>=height[i]) top--; 123 stack[++top]=height[i]; 124 pos[top]=i-1; 125 ansa[top]=ansa[top-1]+(LL)(suma[pos[top]]-suma[pos[top-1]])*(LL)(stack[top]-k+1); 126 ansb[top]=ansb[top-1]+(LL)(sumb[pos[top]]-sumb[pos[top-1]])*(LL)(stack[top]-k+1); 127 if(sa[i]>m) 128 ans+=ansa[top]; 129 else if(sa[i]<m) 130 ans+=ansb[top]; 131 } 132 } 133 printf("%lld ",ans); 134 } 135 return 0; 136 }