hihoCoder #1457 : 後綴自動機四·重複旋律7(後綴自動機 + 拓撲排序)

http://hihocoder.com/problemset/problem/1457ios

 

val[i] 表示狀態i所表示的全部字符串的十進制之和spa

ans= ∑ val[i]
在後綴自動機上,從起始狀態走任意一條路徑到達任意一個狀態,這條路徑上的字符就是到達的狀態的字符串之一code

因此利用拓撲排序,記錄從起始狀態 走到這個狀態的 路徑數,即這個狀態的字符串個數 sumblog

若後綴自動機上有邊u-->v,加的是數字m,sum[v]+=sum[u],val[v]+=val[u]*10+sum[u]*m排序

至於多個串,中間加特殊字符,拓撲排序的時候不走特殊字符邊便可內存

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

const int mod=1e9+7;

#define N 2000001

int tot=1,ch[N<<2][11];
int fa[N<<1],len[N<<1];
int dep[N<<1];
int last=1,p,q,np,nq;

char s[N];

int v[N<<1];
int sa[N<<1];

int sum[N<<1],val[N<<1];

void extend(int c)
{
    len[np=++tot]=len[last]+1;
    dep[np]=dep[last]+1;
    for(p=last;p && !ch[p][c];p=fa[p]) ch[p][c]=np;
    if(!p) fa[np]=1;
    else
    {
        q=ch[p][c];
        if(len[q]==len[p]+1) fa[np]=q;
        else
        {
            nq=++tot;
            fa[nq]=fa[q];
            memcpy(ch[nq],ch[q],sizeof(ch[nq]));
            fa[q]=fa[np]=nq;
            len[nq]=len[p]+1;
            dep[nq]=dep[p]+1;
            for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
        }
    }
    last=np;
}

void ADD(int &x,int y)
{
    x+=y;
    x-=x>=mod ? mod : 0;
}    

int main()
{
    int n;
    scanf("%d",&n);
    int L;
    while(n--)
    {
        scanf("%s",s+1);
        L=strlen(s+1);
        for(int i=1;i<=L;++i) extend(s[i]-'0');
        if(n) extend(10);
    }
    for(int i=1;i<=tot;++i) v[dep[i]]++;
    for(int i=1;i<=tot;++i) v[i]+=v[i-1];
    for(int i=1;i<=tot;++i) sa[v[dep[i]]--]=i;
    sum[1]=1;
    int x;
    for(int i=1;i<tot;++i) 
    {
        x=sa[i];
        for(int j=0;j<10;++j)
            if(ch[x][j]) 
            {
                ADD(sum[ch[x][j]],sum[x]);
                ADD(val[ch[x][j]],(1LL*val[x]*10+1LL*j*sum[x])%mod);
            }
    }
    int ans=0;
    for(int i=1;i<=tot;++i) ADD(ans,val[i]);
    printf("%d",ans);
}

 

時間限制:15000ms
單點時限:3000ms
內存限制:512MB

描述

小Hi平時的一大興趣愛好就是演奏鋼琴。咱們知道一段音樂旋律能夠被表示爲一段數構成的數列。字符串

神奇的是小Hi發現了一部名字叫《十進制進行曲大全》的做品集,顧名思義,這部做品集裏有許多做品,可是全部的做品有一個共同特徵:只用了十個音符,全部的音符都表示成0-9的數字。get

如今小Hi想知道這部做品中全部不一樣的旋律的「和」(也就是把串當作數字,在十進制下的求和,容許有前導0)。答案有可能很大,咱們須要對(10^9 + 7)取摸。string

解題方法提示it

輸入

第一行,一個整數N,表示有N部做品。

接下來N行,每行包含一個由數字0-9構成的字符串S。

全部字符串長度和不超過 1000000。

輸出

共一行,一個整數,表示答案 mod (10^9 + 7)。

樣例輸入
2
101
09
樣例輸出
131
相關文章
相關標籤/搜索