zoukankan      html  css  js  c++  java
  • hiho一下第130周 后缀自动机二·重复旋律7

    后缀自动机四·重复旋律7

    时间限制:15000ms
    单点时限:3000ms
    内存限制:512MB

    描述

    小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一段音乐旋律可以被表示为一段数构成的数列。

    神奇的是小Hi发现了一部名字叫《十进制进行曲大全》的作品集,顾名思义,这部作品集里有许多作品,但是所有的作品有一个共同特征:只用了十个音符,所有的音符都表示成0-9的数字。

    现在小Hi想知道这部作品中所有不同的旋律的“和”(也就是把串看成数字,在十进制下的求和,允许有前导0)。答案有可能很大,我们需要对(10^9 + 7)取摸。

    解题方法提示

    输入

    第一行,一个整数N,表示有N部作品。

    接下来N行,每行包含一个由数字0-9构成的字符串S。

    所有字符串长度和不超过 1000000。

    输出

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

    样例输入
    2
    101
    09
    样例输出
    131
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <time.h>
    #include <string>
    #include <map>
    #include <stack>
    #include <vector>
    #include <set>
    #include <queue>
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int N=2e6+100;
    const int M=1e6+5;
    const long long MOD = 1000000007LL;
    int tot,slink[2*N],trans[2*N][26],minlen[2*N],maxlen[2*N],edpts[2*N];
    string str;
    int n;
    int containPrefix[N],ind[N],ans[2*N+10],cnt[N*2];
    ll sum[N*2],sz_valid[N*2];
    int newstate(int _maxlen,int _minlen,int* _trans,int _slink) {
        maxlen[++tot]=_maxlen;
        minlen[tot]=_minlen;
        slink[tot]=_slink;
        if(_trans)
            for(int i=0; i<11; i++)
                trans[tot][i]=_trans[i];
        return tot;
    }
    int add_char(char ch,int u) {
        int c=ch-'0',v=u;
        int z=newstate(maxlen[u]+1,-1,NULL,0);
        containPrefix[z]=1;
        while(v&&!trans[v][c]) {
            trans[v][c]=z;
            v=slink[v];
        }
        if(!v) {
            minlen[z]=1;
            slink[z]=1;
            ind[0]++;
            return z;
        }
        int x=trans[v][c];
        if(maxlen[v]+1==maxlen[x]) {
            slink[z]=x;
            minlen[z]=maxlen[x]+1;
            ind[x]++;
            return z;
        }
        int y=newstate(maxlen[v]+1,-1,trans[x],slink[x]);
        slink[z]=slink[x]=y;
        ind[y]+=2;
        minlen[x]=minlen[z]=maxlen[y]+1;
        while(v&&trans[v][c]==x) {
            trans[v][c]=y;
            v=slink[v];
        }
        minlen[y]=maxlen[slink[y]]+1;
        return z;
    }
    void init_dag() {
        for ( int i = 0; i <=tot; i++ ) {
            for ( int j = 0; j < 11; j++ ) {
                if ( trans[i][j] > 0 ) {
                    cnt[trans[i][j]] ++;
                }
            }
        }
    }
    
    void topsort(){
        queue<int>q;
        for ( int i = 1; i <=tot; i++ ) {
            if ( cnt[i] == 0 ) {
                q.push(i);
                sz_valid[i] = 1;
                sum[i] = 0;
            }
        }
        while(!q.empty()){
            int i=q.front();
            q.pop();
            for ( int k = 0; k < 11; k++ ) {
                if ( trans[i][k] >0 ) {
                    int j = trans[i][k];
                    if(k < 10) {
                        sz_valid[j] += sz_valid[i];
                        sz_valid[j] %= MOD;
                        sum[j] += sum[i] * 10 + k * sz_valid[i];
                        sum[j] %= MOD;
                    }
                    cnt[j] --;
                    if(cnt[j] == 0) q.push(j);
                }
            }
        }
    }
    int main() {
        cin>>n;
        cin>>str;
        for(int i=1;i<n;i++){
            string ss;
            cin>>ss;
            str=str+":"+ss;
        }
        int pre=newstate(0,0,NULL,-1);;
        tot=1;
        int len=str.length();
        for(int i=0; i<len; i++) {
            pre=add_char(str[i],pre);
        }
        init_dag();
        topsort();
        ll ans=0;
        for ( int i = 1; i <=tot; i++ ) {
            ans += sum[i];
            ans %= MOD;
        }
        cout << ans << endl;
        return 0;
    }
  • 相关阅读:
    WCF相关
    MiniUI级联
    大家一起来学 NHibernate+NUnit (VS2012+SQL Server2008)
    C# 复杂算法
    sql自定义日期函数,返回范围内日期和星期数表。
    RDLC开发笔记
    解决IE7和IE6不支持javaScript中的indexOf函数的问题
    Sql获取周、月、年的首尾时间。
    Sql Server中实现Mysql中的group_concat函数效果
    RDLC隔行变色的实现
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6347486.html
Copyright © 2011-2022 走看看