当前位置: 首页 > news >正文

hihocoder 1457(后缀自动机+拓扑排序)

题意

给定若干组由数字构成的字符串,求所有不重复子串的和(把他们看成十进制),答案mod(1e9+7)

 

题解:

类似后缀数组的做法,把字符串之间用':'连接,这里用':'是因为':'的ascii码恰好是9的下一个

然后建立后缀自动机。

之后把其实只要把其中的所有':'边删去,就可以进行转移了

如果x连向了y,边权是c,那么有转移

dp[y] += dp[x]*10 + c*sz[x]

所以只要拓扑排序一下就好

 

(写这题wa了好几次,主要是在删边建立新图的过程出了问题)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
typedef long long LL;
int n = 0, len, st;
const int maxL = 2e6 + 100;
const int MOD = 1e9 + 7;
int maxlen[2*maxL], minlen[2*maxL], trans[2*maxL][12], slink[2*maxL], col[2*maxL];
LL in[2*maxL], dp[2*maxL], sz[2*maxL];
int new_state(int _maxlen, int _minlen, int *_trans, int _slink){
    maxlen[n] = _maxlen;
    minlen[n] = _minlen;
    for(int i = 0; i < 11; i++){
        if(_trans == NULL)
            trans[n][i] = -1;
        else
            trans[n][i] = _trans[i];
    }
    slink[n] = _slink;
    return n++;
}

int add_char(char ch, int u){
    int c = ch - '0';
    int z = new_state(maxlen[u]+1, -1, NULL, -1);
    int v = u;
    while(v != -1 && trans[v][c] == -1){
        trans[v][c] = z;
        v = slink[v];
    }
    if(v == -1){
        minlen[z] = 1;
        slink[z] = 0;
        return z;
    }
    int x = trans[v][c];
    if(maxlen[v] + 1 == maxlen[x]){
        minlen[z] = maxlen[x] + 1;
        slink[z] = x;
        return z;
    }
    int y = new_state(maxlen[v] + 1, -1, trans[x], slink[x]);
    slink[y] = slink[x];
    minlen[x] = maxlen[y] + 1;
    slink[x] = y;
    minlen[z] = maxlen[y] + 1;
    slink[z] = y;
    int w = v;
    while(w != -1 && trans[w][c] == x){
        trans[w][c] = y;
        w = slink[w];
    }
    minlen[y] = maxlen[slink[y]] + 1;
    return z;
}

char str[maxL];
queue<int> Q;
int main()
{
    freopen("a.txt", "r", stdin);
    int N;
    cin>>N;
    st = new_state(0, 0, NULL, -1);
    while(N--){
        cin>>str;
        int len = strlen(str);
        for(int i = 0; i < len; i++) {
            st = add_char(str[i], st);
        }
        st = add_char(':', st);
    }
    Q.push(0); col[0] = 1;
    while(!Q.empty()){
        int x = Q.front(); Q.pop();
        for(int c = 0; c < 10; c++){
            int y = trans[x][c];
            if(y == -1) continue;
            if(!col[y]) Q.push(y); col[y] = 1;
            in[y]++;
        }
    }
    Q.push(0); sz[0] = 1;
    while(!Q.empty()){
        int x = Q.front(); Q.pop();
        for(int c = 0; c < 10; c++){
            int y = trans[x][c];
            if(y == -1) continue;
            in[y]--;
            if(in[y] == 0) Q.push(y);
            (sz[y] += sz[x]) %= MOD;
            (dp[y] += dp[x]*10 + c*sz[x]) %= MOD;
        }
    }
    LL ans = 0;
    /*
    for(int i = 0; i <  n; i++){
        for(int c = 0; c < 10; c++){
            if(trans[i][c] == -1) continue;
            cout<<i<<" "<<trans[i][c]<<" "<<c<<endl;
        }
    }*/
    //for(int i = 0; i < n; i++) cout<<dp[i]<<" "; cout<<endl;
    for(int i = 0; i < n; i++) (ans += dp[i]) %= MOD;
    cout<<ans<<endl;
    return 0;
}

 

转载于:https://www.cnblogs.com/Saurus/p/7101021.html

相关文章:

  • Gnocchi+Aodh服务简析
  • 给wordpress导航菜单添加个性图标
  • BZOJ 3170 [Tjoi 2013]松鼠聚会
  • 面向云数据中心的现代数据管理架构
  • 分布式光伏发电及配电网的保护机制探究
  • 光伏组件价格跳水,企业的未来何去何从?
  • 从智能家居的发展看对讲企业的定位
  • 六个对CRM数据分析至关重要的特性
  • Tego与Smartrac合作开发RFID解决方案用于复杂的工业环境
  • 交通部回应共享单车新政:实名制如何确保信息安全
  • Sublime字体设置
  • CS安装卸载测试总结
  • 联发科将推Helio P35:10nm工艺 千元机福音
  • Linux中的硬链接与软链接
  • 中国电信用软件定义来“去电信化”
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 【前端学习】-粗谈选择器
  • Android系统模拟器绘制实现概述
  • EventListener原理
  • HTTP那些事
  • HTTP中GET与POST的区别 99%的错误认识
  • Java 23种设计模式 之单例模式 7种实现方式
  • Java精华积累:初学者都应该搞懂的问题
  • Linux后台研发超实用命令总结
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • Python学习笔记 字符串拼接
  • spring-boot List转Page
  • 关于使用markdown的方法(引自CSDN教程)
  • 聚簇索引和非聚簇索引
  • 开发基于以太坊智能合约的DApp
  • 来,膜拜下android roadmap,强大的执行力
  • 如何在GitHub上创建个人博客
  • 十年未变!安全,谁之责?(下)
  • 通过git安装npm私有模块
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • "无招胜有招"nbsp;史上最全的互…
  • #android不同版本废弃api,新api。
  • #stm32驱动外设模块总结w5500模块
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • $L^p$ 调和函数恒为零
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (30)数组元素和与数字和的绝对差
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (一)基于IDEA的JAVA基础10
  • *上位机的定义
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .md即markdown文件的基本常用编写语法
  • .net Stream篇(六)
  • .net下的富文本编辑器FCKeditor的配置方法
  • .NET学习教程二——.net基础定义+VS常用设置
  • /var/lib/dpkg/lock 锁定问题
  • @configuration注解_2w字长文给你讲透了配置类为什么要添加 @Configuration注解