題目
在\(dag\)上跑乙個\(dp\)就好了
設\(ans_i\)表示到了\(sam\)的\(i\)位置上所有的子串形成的數的和,之後我們順便記錄乙個方案數\(d_i\)
之後我們直接轉移就好了
\[ans_v+=ans_u\times 10+w[u,v]\times d_u
\]\[d_v+=d_u
\]答案是\(\sum_^ ans_i\)
**
#include#include#include#include#define maxn 1000005
#define re register
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const ll mod=1e9+7;
int n,m,cnt=1,lst=1;
char s[maxn];
int fa[maxn<<1],len[maxn<<1],son[maxn<<1][11];
ll ans[maxn<<1],d[maxn<<1];
int q[maxn<<1],top,r[maxn<<1];
inline void ins(int c)
int x=son[f][c];
if(len[f]+1==len[x])
int y=++cnt;
len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
for(re int i=0;i<=10;i++) son[y][i]=son[x][i];
while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
}int main()
for(re int i=1;i<=cnt;i++)
for(re int j=0;j<=10;j++) r[son[i][j]]++;
q[++top]=1,d[1]=1;
for(re int i=1;i<=top;i++)
if(!son[q[i]][10]) continue;
r[son[q[i]][10]]--;
if(!r[son[q[i]][10]]) q[++top]=son[q[i]][10];
} ll now=0;
for(re int i=2;i<=cnt;i++) now=(now+ans[i])%mod;
printf("%lld\n",now);
return 0;
}
hihocoder1465 字尾自動機 迴圈同構
hihocoder1465 描述小hi平時的一大興趣愛好就是演奏鋼琴。我們知道一段 旋律可以被表示為一段數構成的數列。小hi發現旋律可以迴圈,每次把一段旋律裡面最前面乙個音換到最後面就成為了原旋律的 迴圈相似旋律 還可以對 迴圈相似旋律 進行相同的變換能繼續得到原串的 迴圈相似旋律 小hi對此產生了...
字尾自動機
基礎知識 step i 表示的是字串i在原字串中的位置。pareint i 表示root到parent i 的子串是root到i的最長字尾。字尾自動機遍歷可以得到原字串的所有子串。特殊技巧 一 字尾自動機的不同子串數有兩種求法 1.ans step i step parent i 1 i cnt 2...
字尾自動機
常用於處理字串問題,可以高效解決許多字串問題。有點像將乙個字串的所有字尾都建在乙個ac自動機上,但不同的是字尾自動機的節點數最多為2 n,因為它只記錄需要記錄的點,一些沒有記錄東西的點可以視為與下面有價值的節點並在一起,這樣大大降低了時間複雜度和空間複雜度。對於每乙個節點記錄它的後面加上每個字元後字...