Description
SD有一名神犇叫做Oxer,他觉得字符串的题目都太水了,于是便出了一道题来虐蒟蒻yts1999。
他给出了一个字符串T,字符串T中有且仅有4种字符 'A', 'B', 'C', 'D'。现在他要求蒟蒻yts1999构造一个新的字符串S,构造的方法是:进行多次操作,每一次操作选择T的一个子串,将其加入S的末尾。
对于一个可构造出的字符串S,可能有多种构造方案,Oxer定义构造字符串S所需的操作次数为所有构造方案中操作次数的最小值。
Oxer想知道对于给定的正整数N和字符串T,他所能构造出的所有长度为N的字符串S中,构造所需的操作次数最大的字符串的操作次数。
蒟蒻yts1999当然不会做了,于是向你求助。
Input
第一行包含一个整数N,表示要构造的字符串长度。
第二行包含一个字符串T,T的意义如题所述。
Output
输出文件包含一行,一个整数,为你所求出的最大的操作次数。
Sample Input
5
ABCCAD
ABCCAD
Sample Output
5
HINT
【样例说明】
例如字符串"AAAAA",该字符串所需操作次数为5,不存在能用T的子串构造出的,且所需操作次数比5大的字符串。
【数据规模和约定】
对于100%的数据,1 ≤ N ≤ 10^18,1 ≤ |T| ≤ 10^5。
Solution
Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<queue> 5 #define N (200009) 6 #define LL long long 7 using namespace std; 8 9 LL n,id; 10 char s[N]; 11 queue<int>Q; 12 int dis[N],vis[N]; 13 14 struct Matrix 15 { 16 LL m[5][5]; 17 Matrix(){memset(m,0,sizeof(m));} 18 19 Matrix operator * (const Matrix &b) const 20 { 21 Matrix c; 22 for (int i=0; i<4; ++i) 23 for (int j=0; j<4; ++j) 24 c.m[i][j]=1e18; 25 for (int k=0; k<4; ++k) 26 for (int i=0; i<4; ++i) 27 for (int j=0; j<4; ++j) 28 c.m[i][j]=min(c.m[i][j],m[i][k]+b.m[k][j]); 29 return c; 30 } 31 }A,G; 32 33 Matrix Qpow(Matrix a,LL b) 34 { 35 Matrix ans; 36 for (int i=0; i<4; ++i) ans.m[i][i]=1; 37 while (b) 38 { 39 if (b&1) ans=ans*a; 40 a=a*a; b>>=1; 41 } 42 return ans; 43 } 44 45 struct SAM 46 { 47 int son[N][4],fa[N],step[N]; 48 int p,q,np,nq,last,cnt; 49 SAM(){last=cnt=1;} 50 51 void Insert(int x) 52 { 53 p=last; np=last=++cnt; step[np]=step[p]+1; 54 while (p && !son[p][x]) son[p][x]=np, p=fa[p]; 55 if (!p) fa[np]=1; 56 else 57 { 58 q=son[p][x]; 59 if (step[q]==step[p]+1) fa[np]=q; 60 else 61 { 62 nq=++cnt; step[nq]=step[p]+1; 63 memcpy(son[nq],son[q],sizeof(son[q])); 64 fa[nq]=fa[q]; fa[q]=fa[np]=nq; 65 while (son[p][x]==q) son[p][x]=nq, p=fa[p]; 66 } 67 } 68 } 69 void Build_Matrix() 70 { 71 for (int i=0; i<4; ++i) 72 for (int j=0; j<4; ++j) 73 A.m[i][j]=1e18; 74 for (int s=0; s<4; ++s) 75 { 76 while (!Q.empty()) Q.pop(); 77 memset(vis,false,sizeof(vis)); 78 vis[son[1][s]]=true; 79 Q.push(son[1][s]); dis[son[1][s]]=1; 80 while (!Q.empty()) 81 { 82 int x=Q.front(); Q.pop(); 83 for (int i=0; i<4; ++i) 84 if (son[x][i] && !vis[son[x][i]]) 85 vis[son[x][i]]=true,Q.push(son[x][i]),dis[son[x][i]]=dis[x]+1; 86 else A.m[s][i]=min(A.m[s][i],(LL)dis[x]); 87 } 88 } 89 } 90 }SAM; 91 92 LL check(LL x) 93 { 94 LL Min=1e18; 95 G=Qpow(A,x); 96 for (int i=0; i<4; ++i) 97 for (int j=0; j<4; ++j) 98 Min=min(Min,G.m[i][j]); 99 return Min>=n; 100 } 101 102 int main() 103 { 104 scanf("%lld%s",&n,s); 105 for (int i=0,l=strlen(s); i<l; ++i) 106 SAM.Insert(s[i]-'A'); 107 SAM.Build_Matrix(); 108 LL l=0,r=1e18,ans; 109 while (l<=r) 110 { 111 LL mid=(l+r)>>1; 112 if (check(mid)) ans=mid,r=mid-1; 113 else l=mid+1; 114 } 115 printf("%lld ",ans); 116 }