【BZOJ-4180】字符串计数 后缀自动机 + 矩阵乘法
4180: 字符串计数
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 146 Solved: 66
[Submit][Status][Discuss]
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。
Source
Solution
人傻不会做...于是看的题解...
Code
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> using namespace std; #define LL long long #define MAXN 500010 #define INF (1LL<<62) LL N; char S[MAXN]; int last=1,sz=1,root=1,par[MAXN<<1],len[MAXN<<1],son[MAXN][4]; LL f[MAXN][4]; inline void Extend(int c) { int cur=++sz,p=last; len[cur]=len[p]+1; while (p && !son[p][c]) son[p][c]=cur,p=par[p]; if (!p) par[cur]=root; else { int q=son[p][c]; if (len[p]+1==len[q]) par[cur]=q; else { int nq=++sz; memcpy(son[nq],son[q],sizeof(son[nq])); len[nq]=len[p]+1; par[nq]=par[q]; while (p && son[p][c]==q) son[p][c]=nq,p=par[p]; par[q]=par[cur]=nq; } } last=cur; } bool visit[MAXN<<1]; inline void Dfs(int now) { if (visit[now]) return; visit[now]=1; for (int c=0; c<4; c++) if (son[now][c]) Dfs(son[now][c]),f[now][c]=INF; else f[now][c]=1; for (int c=0; c<4; c++) if (son[now][c]) for (int cc=0; cc<4; cc++) f[now][cc]=min(f[now][cc],f[son[now][c]][cc]+1); } struct Matrix{ LL a[4][4]; Matrix() {for (int i=0; i<4; i++) for (int j=0; j<4; j++) a[i][j]=INF;} LL* operator [](int x) { return a[x]; } }X; Matrix operator * (Matrix &A,Matrix &B) { Matrix C; for (int i=0; i<4; i++) for (int j=0; j<4; j++) for (int k=0; k<4; k++) C[i][j]=min(C[i][j],A[i][k]+B[k][j]); return C; } Matrix operator ^ (Matrix x,LL y) { Matrix re; memset(re.a,0,sizeof(re.a)); for (int i=0; i<4; i++) re[i][i]=1; for ( ; y; y>>=1,x=x*x) if (y&1) re=re*x; return re; } inline bool check(LL x) { Matrix B=X^x; for (int i=0; i<4; i++) for (int j=0; j<4; j++) if (B[i][j]+1<=N) return 1; return 0; } int main() { scanf("%lld%s",&N,S+1); int L=strlen(S+1); for (int i=1; i<=L; i++) Extend(S[i]-'A'); Dfs(root); for (int i=0; i<4; i++) for (int j=0; j<4; j++) X[i][j]=f[son[root][i]][j]; // for (int i=0; i<4; i++,puts("")) // for (int j=0; j<4; j++) printf("%I64d ",X[i][j]==INF? -1:X[i][j]); LL l=0,r=N+1,mid,ans=0; while (l<=r) { mid=(l+r)>>1; if (check(mid)) l=mid+1; else r=(ans=mid)-1; } printf("%lld\n",ans); return 0; } /* 5 ABCCAD */
——It's a lonely path. Don't make it any lonelier than it has to be.