很好的一个题目。对于理解后缀自动机很有用。

题目给你若干数字串,总长度不超过100000,任意一个串的任意一个子串都可以拿出来单独的作为一个数字。同一个数字只算一次。

问所有不同数字的和为多少?

嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯嗯

首先由于字符串的数字很多,我们可以把么多串连接成一个串,每个串用[10]隔开就好了。

然后往后面搜,对于当前状态,保存以这个状态为终点的所有路径的和,每次记录有多少种路径走到当前状态,对于连接x到达的下一个状态就是这样来计算的:f[next[]]+=f[cur]*10+num[]*x;这个式子不难理解。

于是我们把所有的点都拓扑排序一下,然后这样一路计算下去就可以了。(按step值来排序)

有坑提示:注意前导零,注意不能用num是否等于0来判断当前状态能否到达,因为num对2012取模了,所以判断无意义。

召唤代码君:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define maxn 300300
using namespace std; int next[maxn][11],pre[maxn],step[maxn];
int N,last,n,ans;
int p,q,np,nq;
int f[maxn],cnt[maxn],g[maxn],t[maxn];
char s[maxn];
bool mark[maxn]; int add()
{
N++; mark[N]=false;
t[N]=cnt[N]=g[N]=f[N]=pre[N]=step[N]=0;
for (int i=0; i<11; i++) next[N][i]=0;
return N;
} void insert(int x)
{
p=last,np=add(),step[np]=step[last]+1,last=np;
while (p!=-1 && next[p][x]==0) next[p][x]=np,p=pre[p];
if (p==-1) return;
q=next[p][x];
if (step[q]==step[p]+1) { pre[np]=q; return; }
nq=add(),step[nq]=step[p]+1,pre[nq]=pre[q];
for (int i=0; i<11; i++) next[nq][i]=next[q][i];
pre[np]=pre[q]=nq;
while (p!=-1 && next[p][x]==q) next[p][x]=nq,p=pre[p];
} int main()
{
while (scanf("%d",&n)!=EOF)
{
N=-1;N=add();pre[0]=-1;last=ans=0;
while (n--)
{
scanf("%s",s);
for (int i=0; s[i]; i++) insert(s[i]-'0');
insert(10);
}
for (int i=0; i<=N; i++) cnt[step[i]]++;
for (int i=1; i<=N; i++) cnt[i]+=cnt[i-1];
for (int i=0; i<=N; i++) g[--cnt[step[i]]]=i;
t[0]=1; mark[0]=true;
for (int p=0; p<=N; p++)
{
int cur=g[p];
if (next[0][0]==cur && next[0][0]!=0) continue;
if (!mark[cur]) continue;
ans=(ans+f[cur])%2012;
for (int i=0; i<=9; i++)
{
if (next[cur][i]==0) continue;
f[next[cur][i]]=(f[next[cur][i]]+f[cur]*10+t[cur]*i)%2012;
t[next[cur][i]]=(t[next[cur][i]]+t[cur])%2012;
mark[next[cur][i]]=true;
}
}
printf("%d\n",ans);
}
return 0;
}

  

HDU4436_str2int的更多相关文章

随机推荐

  1. 所有权链(Ownership Chain)

    所有权链(Ownership Chain)是特殊的权限评估方式,常见拥有所有权的数据库对象是:数据库对象,数据库角色(Role),和架构(Schema),在创建数据库角色,或架构时,SQL Serve ...

  2. AgileRepository - 一个基于接口的Repository快速开发库

    AgileRepository 这是一个可以帮助你快速开发Repository的lib.有点像SpringData JPA根据方法名.注解来自动生成查询方法的功能. 对于一些简单的查询,只需要定义接口 ...

  3. Spring学习(十八)----- Spring AOP+AspectJ注解实例

    我们将向你展示如何将AspectJ注解集成到Spring AOP框架.在这个Spring AOP+ AspectJ 示例中,让您轻松实现拦截方法. 常见AspectJ的注解: @Before – 方法 ...

  4. 大话 .Net 之内存管理

    在一次偶然的机会中,我来到了恒生的大家庭.又在一次偶然的机会中,我很荣幸的被勇哥信任并让我写一篇季刊的文章.可能人生之中充满了无数次的偶然机会,我们只有抓住眼前的“偶然”,才可以创建人生.当我接到这个 ...

  5. File System Object(FSO对象)B

    一.实例FSO获取当前路径下的文件 Sub Fsotest() Dim Fso As New FileSystemObject, Path As String, File Path = ThisWor ...

  6. Flink架构分析之HA

    抽象 LeaderElectionService 这个接口用于从一组竞选者中选出一个leader,其start方法需要传递一个LeaderContender竞选者作为参数,如果有多个竞选者,则每一个竞 ...

  7. 从零开始的Python学习Episode 16——模块

    一.模块 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相 ...

  8. 基于C#的机器学习--贝叶斯定理-执行数据分析解决肇事逃逸之谜

    贝叶斯定理-执行数据分析解决肇事逃逸之谜 ​ 在这一章中,我们将: 应用著名的贝叶斯定理来解决计算机科学中的一个非常著名的问题. 向您展示如何使用贝叶斯定理和朴素贝叶斯来绘制数据,从真值表中发现异常值 ...

  9. Python基础系列讲解——TCP协议的socket编程

    前言 我们知道TCP协议(Transmission Control Protocol, 传输控制协议)是一种面向连接的传输层通信协议,它能提供高可靠性通信,像HTTP/HTTPS等网络服务都采用TCP ...

  10. Java多线程编程之不可变对象模式

           在多线程环境中,为了保证共享数据的一致性,往往需要对共享数据的使用进行加锁,但是加锁操作本身就会带来一定的开销,这里可以使用将共享数据使用不可变对象进行封装,从而避免加锁操作. 1. 模 ...