题意

给定若干组由数字构成的字符串,求所有不重复子串的和(把他们看成十进制),答案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 = , len, st;
const int maxL = 2e6 + ;
const int MOD = 1e9 + ;
int maxlen[*maxL], minlen[*maxL], trans[*maxL][], slink[*maxL], col[*maxL];
LL in[*maxL], dp[*maxL], sz[*maxL];
int new_state(int _maxlen, int _minlen, int *_trans, int _slink){
maxlen[n] = _maxlen;
minlen[n] = _minlen;
for(int i = ; i < ; i++){
if(_trans == NULL)
trans[n][i] = -;
else
trans[n][i] = _trans[i];
}
slink[n] = _slink;
return n++;
} int add_char(char ch, int u){
int c = ch - '';
int z = new_state(maxlen[u]+, -, NULL, -);
int v = u;
while(v != - && trans[v][c] == -){
trans[v][c] = z;
v = slink[v];
}
if(v == -){
minlen[z] = ;
slink[z] = ;
return z;
}
int x = trans[v][c];
if(maxlen[v] + == maxlen[x]){
minlen[z] = maxlen[x] + ;
slink[z] = x;
return z;
}
int y = new_state(maxlen[v] + , -, trans[x], slink[x]);
slink[y] = slink[x];
minlen[x] = maxlen[y] + ;
slink[x] = y;
minlen[z] = maxlen[y] + ;
slink[z] = y;
int w = v;
while(w != - && trans[w][c] == x){
trans[w][c] = y;
w = slink[w];
}
minlen[y] = maxlen[slink[y]] + ;
return z;
} char str[maxL];
queue<int> Q;
int main()
{
freopen("a.txt", "r", stdin);
int N;
cin>>N;
st = new_state(, , NULL, -);
while(N--){
cin>>str;
int len = strlen(str);
for(int i = ; i < len; i++) {
st = add_char(str[i], st);
}
st = add_char(':', st);
}
Q.push(); col[] = ;
while(!Q.empty()){
int x = Q.front(); Q.pop();
for(int c = ; c < ; c++){
int y = trans[x][c];
if(y == -) continue;
if(!col[y]) Q.push(y); col[y] = ;
in[y]++;
}
}
Q.push(); sz[] = ;
while(!Q.empty()){
int x = Q.front(); Q.pop();
for(int c = ; c < ; c++){
int y = trans[x][c];
if(y == -) continue;
in[y]--;
if(in[y] == ) Q.push(y);
(sz[y] += sz[x]) %= MOD;
(dp[y] += dp[x]* + c*sz[x]) %= MOD;
}
}
LL ans = ;
/*
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 = ; i < n; i++) (ans += dp[i]) %= MOD;
cout<<ans<<endl;
return ;
}

最新文章

  1. SpringBoot前世今生
  2. Hive的三种安装方式(内嵌模式,本地模式远程模式)
  3. [Unity3D]自制UnityForAndroid二维码扫描插件
  4. 【BZOJ】1041: [HAOI2008]圆上的整点(几何)
  5. Topcoder SRM 661 (Div.1) 250 MissingLCM - 数论
  6. 面向接口可扩展框架之“Mvc扩展框架及DI”
  7. PHP --字符串编码转换(自动识别原编码)
  8. c++日历v1.0版本
  9. Leetcode Pasacl&#39;sTriangle
  10. 关于WSL(Windows上的Linux子系统)的介绍
  11. asp.net 未能加载文件或程序集“WebApi”或它的某一个依赖项。试图加载格式不正确的程序。
  12. SpriteBuilder中使用GUI界面快速搭建RPG游戏中的地图名显示动画
  13. Oracle XMLTYPE数据类型创建及插入
  14. bash配色
  15. Flask主要知识点
  16. 3DLut表实现log视频的后期调色原理
  17. 【BZOJ1816】[CQOI2010]扑克牌(二分,贪心)
  18. Java 8新特性之lambda(八恶人-2)
  19. TCP/UDP常见端口
  20. django中celery的使用

热门文章

  1. struts2的token interceptor
  2. DevOps - 版本控制 - Bitbucket
  3. JS高级. 02 面向对象、创建对象、构造函数、自定义构造函数、原型
  4. Git----将本地代码推送到远程仓库
  5. python2.7入门---Number(数字)
  6. Verilog 初级入门概念
  7. JAVA大作业汇总2
  8. PHP.40-TP框架商城应用实例-后台15-商品属性与库存量1-不同商品(唯一属性、可选属性),属性类型
  9. vuex的使用及持久化state的方式详解
  10. LeetCode高频题目(100)汇总-Java实现