思路

后缀自动机题目,题目本质上是要求求出所有不同的子串的和,SAM每个节点中存放的子串互不相同,所以对于每个节点的sum,可以发现是可以递推的,每个点对子节点贡献是sum[x]*10+c*sz[x],对于单个串,sz[x]就是maxlen[x]-minlen[x]+1,现在有多个串,可以用其他字符分割,然后建出SAM,注意到新的合法的sz是不能跨越两个不同的串的,SAM上的一条路径就是一个子串,所以求sz等价于统计不经过分隔符的路径条数,拓扑排序即可

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <iostream>
#define int long long
using namespace std;
const int MAXN = 1000100*2;
const int MOD = 1000000007;
int cnt,trans[MAXN][11],maxlen[MAXN],sz[MAXN],in[MAXN],suflink[MAXN],sum[MAXN],ok[MAXN],n,len=0;
char s[MAXN],t[MAXN];
int new_state(int _maxlen,int *_trans,int _suflink){
++cnt;
maxlen[cnt]=_maxlen;
if(_trans)
for(int i=0;i<11;i++)
trans[cnt][i]=_trans[i];
suflink[cnt]=_suflink;
return cnt;
}
int add_len(int u,int c){
int z=new_state(maxlen[u]+1,NULL,0);
if(c==10)
ok[z]=true;
while(u&&(!trans[u][c])){
trans[u][c]=z;
u=suflink[u];
}
if(!u){
suflink[z]=1;
return z;
}
int v=trans[u][c];
if(maxlen[v]==maxlen[u]+1){
suflink[z]=v;
return z;
}
int y=new_state(maxlen[u]+1,trans[v],suflink[v]);
suflink[z]=suflink[v]=y;
while(u&&trans[u][c]==v){
trans[u][c]=y;
u=suflink[u];
}
return z;
}
queue<int> q;
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%s",t+1);
int midlen=strlen(t+1);
if(i!=1)
s[++len]='0'+10;
for(int j=1;j<=midlen;j++)
s[len+j]=t[j];
len+=midlen;
}
s[len+1]='\0';
// printf("%s\n%lld\n",s+1,len);
int pre=1;
cnt=1;
for(int i=1;i<=len;i++)
pre=add_len(pre,s[i]-'0');
// printf("cnt=%d\n",cnt);
for(int i=1;i<=cnt;i++){
for(int j=0;j<11;j++)
if(trans[i][j])
in[trans[i][j]]++;
}
for(int i=1;i<=cnt;i++)
if(!in[i])
q.push(i);
sz[1]=1;
sum[1]=0;
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=0;i<11;i++){
if(trans[x][i]){
if(i<10){
sz[trans[x][i]]=(sz[x]+sz[trans[x][i]])%MOD;
sum[trans[x][i]]=(sum[trans[x][i]]+sum[x]*10%MOD+i*sz[x]%MOD)%MOD;
}
in[trans[x][i]]--;
if(!in[trans[x][i]])
q.push(trans[x][i]);
}
}
}
int ans=0;
for(int i=1;i<=cnt;i++)
if(!ok[i])
ans=(ans+sum[i])%MOD;
printf("%lld\n",ans);
return 0;
}

HIHOcoder 1457 后缀自动机四·重复旋律7的更多相关文章

  1. hihocoder 1457 后缀自动机四·重复旋律7 求不同子串的和

    描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的是小Hi发现了一部名字叫<十进制进行曲大全>的作品集,顾名思义,这部作品集里有许多作品 ...

  2. hihocoder 1457 后缀自动机四·重复旋律7 ( 多串连接处理技巧 )

    题目链接 分析 : 这道题对于单个串的用 SAM 然后想想怎么维护就行了 但是多个串下.可以先将所有的串用一个不在字符集( 这道题的字符集是 '0' ~ '9' ) 链接起来.建立后缀自动机之后 在统 ...

  3. hihoCoder #1457 : 后缀自动机四·重复旋律7(后缀自动机 + 拓扑排序)

    http://hihocoder.com/problemset/problem/1457 val[i] 表示状态i所表示的所有字符串的十进制之和 ans= ∑ val[i]在后缀自动机上,从起始状态走 ...

  4. hihoCoder.1457.后缀自动机四 重复旋律7(广义后缀自动机)

    题目链接 假设我们知道一个节点表示的子串的和sum,表示的串的个数cnt,那么它会给向数字x转移的节点p贡献 \(sum\times 10+c\times cnt\) 的和. 建广义SAM,按拓扑序正 ...

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

    #1457 : 后缀自动机四·重复旋律7 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成 ...

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

    后缀自动机四·重复旋律7 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的 ...

  7. hihocoder #1419 : 后缀数组四·重复旋律4

    #1419 : 后缀数组四·重复旋律4 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构 ...

  8. hihoCoder #1445 : 后缀自动机二·重复旋律5

    #1445 : 后缀自动机二·重复旋律5 时间限制:10000ms 单点时限:2000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数 ...

  9. hihoCoder #1465 : 后缀自动机五·重复旋律8

    http://hihocoder.com/problemset/problem/1465 求S的循环同构串在T中的出现次数 将串S变成SS 枚举SS的每个位置i,求出以i结尾的SS的子串 与 T的最长 ...

随机推荐

  1. C# 调用.bat 提示该命令不是内部命令或外部命令

    前提:双击.bat文件可以执行成功,用C#调用提示该命令不是内部命令或外部命令...... 解决方法:下面代码的红色标注,既要设置.bat文件的文件名FileName,也要设置.bat文件所在的文件夹 ...

  2. datetime处理日期和时间

    datetime.now() # 获取当前datetimedatetime.utcnow() datetime(2017, 5, 23, 12, 20) # 用指定日期时间创建datetime 一.将 ...

  3. 【2017-03-20】HTML基础知识,标记,表格,表格嵌套及布局,超链接

    一.HTML  网站(站点),网页基础知识 HTML是一门编程语言的名字:超文本标记语言 可以理解为:超越了文本的范畴,可以有图片.视频.音频.动画特效等其他内容,用标记的方法进行编程的计算机语言 基 ...

  4. Lua 判断表是否为空方法

    [1]判断表为空的方法 目前为止,Lua语言中判断table表是否为空有三种方式: (1)#table,当table为数组时直接返回table表的长度. (2)当table是字典时,返回table的长 ...

  5. Python pyodbc安装

    1)下面这个链接找个适合自己python版本的文件下载下来 https://pypi.org/project/pyodbc/#files 2)放到scripts下面 3) 在scripts路径上输入c ...

  6. MyEclipse使用Ant打包项目

    本章主要介绍如何使用ant打包发布项目. ant 是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发.在实际软件开发中,有很多地方可以用到ant. 优点 ...

  7. flask 处理表单数据

    处理表单数据 表单数据的处理涉及很多内容,从获取数据到保存数据大致有以下步骤: 1.  解析请求,获取表单数据 2.  对数据进行必要的转换,比如讲勾选框的值转换成python的布尔值 3.  验证数 ...

  8. 编写一个JavaWeb项目

    基本流程:JSP文件显示页面,在前端页面输入赋值,使用form或href超链接传值到Servlet中方法,在Servlet方法中调用Dao层的类对象,将数据传到数据库中,并实现对数据库里的数据的增删改 ...

  9. django自定义错误响应

    在做一个web时,总是会出现各种错误,如400.403.404.500等.一般开发都要做对应的处理,给一些友好提示,或返回一些公益广告等. 在Django中,默认提供了常见的错误处理方式,比如: ha ...

  10. udp编程 实例

    server端 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <er ...