把所有的字符串连接起来,中间用一个未出现的字符分隔开,题意是求这个串的所有子串(中间不含分隔符)形成的数之和。

把这个串加入SAM,对所有子串进行拓扑排序,从前往后统计。

记录到达这个节点的路径个数cnt,以及到达这个节点的总和sum。

设父节点是u,子节点是v

sum[v] = sum[u] * 10 + sum[v] + cnt[v]*j;

cnt[v] += cnt[u];

ans就是把所有的sum加起来。

注意:

1.忽略前导零

2.子串中不要含分隔符

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm> using namespace std; const int MAXN = ;
const int segma_size = ;
const int MOD = ; struct Suffix_Automaton
{
int F[MAXN << ]; //fail
int ant; //sum node
int last; //last point
int ch[MAXN << ][segma_size]; //side
int step[MAXN << ]; //len void init()
{
last = ant = ;
memset(F,,sizeof(F));
memset(ch,,sizeof(ch));
memset(step,,sizeof(step));
return;
} void ins( int x )
{
int t = ++ant, pa = last;
step[t] = step[last] + ;
last = t;
for( ; pa && !ch[pa][x]; pa = F[pa] )
ch[pa][x] = t;
if( pa == ) F[t] = ;
else if( step[pa] + == step[ ch[pa][x] ] )
F[t] = ch[pa][x];
else
{
int nq = ++ant, q = ch[pa][x];
memcpy( ch[nq], ch[q], sizeof(ch[nq]) );
step[nq] = step[pa] + ;
F[nq] = F[q];
F[q] = F[t] = nq;
for( ; pa && ch[pa][x] == q; pa = F[pa] )
ch[pa][x] = nq;
}
}
}; int N;
char str[MAXN + ];
int strL;
Suffix_Automaton SAM;
int r[MAXN << ];
int sum[MAXN << ];
int cnt[MAXN << ]; bool cmp( int a, int b )
{
return SAM.step[a] < SAM.step[b];
} void show()
{
for ( int i = ; i <= SAM.ant; ++i )
{
for ( int j = ; j < ; ++j )
{
printf( "%d ", SAM.ch[i][j] );
}
puts("");
}
return;
} int main()
{
//freopen( "s.txt", "w", stdout );
while ( scanf( "%d", &N ) == )
{
SAM.init();
strL = ;
for ( int n = ; n < N; ++n )
{
if ( strL )
str[strL++] = '' + ;
scanf( "%s", &str[strL] );
strL += strlen( &str[strL] );
}
for ( int i = ; i < strL; ++i )
SAM.ins( str[i] - '' ); for ( int i = ; i <= SAM.ant; ++i )
r[i] = i; sort( r + , r + + SAM.ant, cmp );
memset( sum, , sizeof(int)*(SAM.ant+) );
memset( cnt, , sizeof(int)*(SAM.ant+) ); int ans = ;
cnt[] = ;
for ( int i = ; i <= SAM.ant; ++i )
{
int u = r[i];
if ( i > && !cnt[u] ) continue;
ans = ( ans + sum[u] ) % MOD;
for ( int j = ; j < ; ++j )
{
if ( u == && j == ) continue;
if ( !SAM.ch[u][j] ) continue;
int v = SAM.ch[u][j];
sum[v] = ( sum[u] * + sum[v] + cnt[u] * j ) % MOD;
cnt[v] += cnt[u];
}
}
printf( "%d\n", ans ); }
return ;
}

HDU 4436 str2int (后缀自动机)的更多相关文章

  1. str2int HDU - 4436 (后缀自动机)

    str2int \[ Time Limit: 3000 ms\quad Memory Limit: 131072 kB \] 题意 给出 \(n\) 个串,求出这 \(n\) 个串所有子串代表的数字的 ...

  2. 字符串(多串后缀自动机):HDU 4436 str2int

    str2int Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total S ...

  3. HDU 4436 str2int(后缀自动机)(2012 Asia Tianjin Regional Contest)

    Problem Description In this problem, you are given several strings that contain only digits from '0' ...

  4. HDU 4436 str2int

    str2int Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on HDU. Original ID: 4 ...

  5. HDU 4622 Reincarnation 后缀自动机

    模板来源:http://blog.csdn.net/zkfzkfzkfzkfzkfzkfzk/article/details/9669747 解法参考:http://blog.csdn.net/dyx ...

  6. HDU 4622 Reincarnation 后缀自动机 // BKDRHash(最优hash)

    Reincarnation Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) P ...

  7. HDU 6583 Typewriter(后缀自动机)

    Typewrite \[ Time Limit: 1500 ms\quad Memory Limit: 262144 kB \] 题意 给出一个字符串 \(s\),现在你需要构造出这个字符串,你每次可 ...

  8. Reincarnation HDU - 4622 (后缀自动机)

    Reincarnation \[ Time Limit: 3000 ms\quad Memory Limit: 65536 kB \] 题意 给出一个字符串 \(S\),然后给出 \(m\) 次查询, ...

  9. Good Article Good sentence HDU - 4416 (后缀自动机)

    Good Article Good sentence \[ Time Limit: 3000 ms\quad Memory Limit: 32768 kB \] 题意 给出一个 \(S\) 串,在给出 ...

  10. HDU - 6583 Typewriter (后缀自动机+dp)

    题目链接 题意:你要打印一段字符串,往尾部添加一个字符需要花费p元,复制一段字符到尾部需要花费q元,求打印完全部字符的最小花费. 一开始想的贪心,后来发现忘了考虑p<q的情况了,还纳闷怎么不对. ...

随机推荐

  1. 几位it 前辈的博客

    赵劼 http://blog.zhaojie.me/?page=2 陈硕 http://www.cnblogs.com/Solstice/ 轮子哥 http://www.cnblogs.com/gen ...

  2. Linux 启动、停止、重启tomcat工具(Shell脚本)

    1.   启动 #!/bin/bash pids=`ps -ef | grep java | grep -w tomcat | awk '{print $2}'` #pids=`ps -ef | gr ...

  3. ROS机器人程序设计

      在<ROS机器人程序设计>中,在第二章创建节点时给出一个接收和发送的例子,但是按照书中步骤编译时,遇到按个三个问题,现在罗列出来解决方案供参考. 建议在工作空间直接输入 catkin_ ...

  4. python第一章练习题

    本章总节 练习题 1.简述编译型与解释型语言的区别,且分别列出你知道的哪些语言属于编译型,哪些属于解释 编译型:把源代码编译成机器语言的可执行文件,程序执行的时候执行可执行文件即可. 优点:程序执行不 ...

  5. C# 操作符与表达式

    C#保留了C++所有的操作符,其中指针操作符(*和->)与引用操作符(&)需要有unsafe的上下文.C#摈弃了范围辨析操作符(::),一律改为单点操作符(.).我们不再阐述那些保留的C ...

  6. [JZOJ] 5905. 黑暗之魂(darksoul)

    基环树直径裸题 分别在子树做DP,环上做DP,环上可以用单调队列优化到\(O(n)\) 写起来很麻烦 #include<algorithm> #include<iostream> ...

  7. lincode 680 Split String

    Split String    描述 笔记 数据 评测 Give a string, you can choose to split the string after one character or ...

  8. MySQL选择的执行计划性能底下原因分析--实战案例分析

    MySQL是自动会选择它认为好的执行划,但是MySQL毕竟是程序,还没有达到像人类思考这么智能,还是通过一些按部就班的算法实现最优执行计划(基于cost)的选择.下面就是一个真实的案例,带你来看看My ...

  9. JAVAOOP多态

    概念:不同对象对于同一个操作做出的相应不同 实现方法:父类:抽象类 抽象方法 子类:普通类 重写抽象方法 同名 父类:普通类 普通方法 子类:普通类 普通方法 同名 父类:接口 抽象方法 实现类:普通 ...

  10. 再次写给VC++ Windows开发者

    距离我的上一篇文章--写给VC++ Windows开发的初学者已经4年多时间过去了,感慨于时光如梭之余,更感慨于这么多年来(从1998年我初学VC 算起吧)到如今其实我仍然还只是个初学者而已.看看之前 ...