HDU4436_str2int
很好的一个题目。对于理解后缀自动机很有用。
题目给你若干数字串,总长度不超过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的更多相关文章
随机推荐
- AxWebBrowser 实现的多进程浏览器 (一)
我们使用 C#/VB.NET 进行 Trident 内核浏览器编程,大多都是单进程的,当打开的页面较多时比较容易出现卡死等情况. 单进程浏览器简单示例: Public Class formBrowse ...
- Java将List<T>集合组装成树(Tree)树结构组装
把列表转换为树结构 /** * 把列表转换为树结构 * * @param originalList 原始list数据 * @param keyName 作为唯一标示的字段名称 * @return 组装 ...
- 用Python做一个翻译软件
前两天吃了平哥的一波狗粮,他给女朋友写了一个翻译软件,自己真真切切的感受到了程序员的浪漫.在学习requests请求的时候做过类似的Demo,给百度翻译发送一个post请求可以实现任意词组的翻译,利用 ...
- ceilometer 源码分析(polling)(O版)
一.简单介绍ceilometer 这里长话短说, ceilometer是用来采集openstack下面各种资源的在某一时刻的资源值,比如云硬盘的大小等.下面是官网现在的架构图 这里除了ceilomet ...
- linux递归查找文件内容并替换
sed -i 's/原字符串/替换后字符串/g' `grep '搜索关键字' -rl /data/目标目录/ --include "*.html"` 上面是递归查找目录中所有的HT ...
- alias命令详情
基础命令学习目录首页 原文链接:http://c.biancheng.net/view/938.html 给命令设置别名,你可以把它当作命令的"小名",但是这样做有什么意义呢? 比 ...
- C++多态深入分析!
以下分析是基于VS2010的.以后会使用G++分析看看G++如何处理多态! // polymorphic_test.cpp : 定义控制台应用程序的入口点. // /** 特别注意:实现C++多态,除 ...
- (转)Django配置数据库读写分离
转:https://blog.csdn.net/Ayhan_huang/article/details/78784486 转:http://www.cnblogs.com/dreamer-fish/p ...
- PHP Filter 函数 日常可用
PHP Filter 函数 PHP Filesystem PHP FTP PHP Filter 简介 PHP 过滤器用于对来自非安全来源的数据(比如用户输入)进行验证和过滤. 安装 filter 函数 ...
- No.101_第二次团队会议
时间的敲定 在这一次的会议中,明确了任务目标,将任务进行合理分配,并且规划了整个任务的时间节点,这对团队来说非常重要. 一.最终项目 在上一节课的时候,我们最终没有拿到学霸开发项目,最后爬虫也被选走了 ...