str2int

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1568    Accepted Submission(s): 540

Problem Description
In this problem, you are given several strings that contain only digits from '0' to '9', inclusive.
An example is shown below.
101
123
The set S of strings is consists of the N strings given in the input file, and all the possible substrings of each one of them.
It's boring to manipulate strings, so you decide to convert strings in S into integers.
You can convert a string that contains only digits into a decimal integer, for example, you can convert "101" into 101, "01" into 1, et al.
If an integer occurs multiple times, you only keep one of them. 
For example, in the example shown above, all the integers are 1, 10, 101, 2, 3, 12, 23, 123.
Your task is to calculate the remainder of the sum of all the integers you get divided by 2012.
 
Input
There are no more than 20 test cases.
The test case starts by a line contains an positive integer N.
Next N lines each contains a string consists of one or more digits.
It's guaranteed that 1≤N≤10000 and the sum of the length of all the strings ≤100000.
The input is terminated by EOF.
 
Output
An integer between 0 and 2011, inclusive, for each test case.
 
Sample Input
5
101
123
09
000
1234567890
 
Sample Output
202
 
Source
 

题意: n个字符串,对于每一个子串可以表示为一个数字, 求所有子串的数字和相加对2012取模,, 相同数字只算一次。

这题可以先把n个字符串用一个没有出现过的字符隔开连起来。然后求sa, lcp。

我们可以先看一个简单的例子。

s = 12345

num[1] = 1             sum[1] = 1

num[2] = 12           sum[2] = 1 + 12

num[3] = 123         sum[3] = 1 + 12 + 123

num[4] = 1234       sum[4] = 1 + 12 + 123 + 1234

num[5] = 12345     sum[5] = 1 + 12 + 123 + 1234 + 12345

如果求[3, 4]  , 只需要 sum[5] - sum[2] - num[2] * (10 + 100 + 1000);

判重时 只要从 i+ lcp[rank[i]]  开始算就可以了,,因为公共前缀那一部分 在前面已经算了。

上代码。。

 #include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
const int mod = ;
const int maxn = 2e5+;
int sum [maxn], num[maxn];
string s;
int sa[maxn], Rank[maxn], tmp[maxn], lcp[maxn];
int k, len;
bool cmp(int i, int j)
{
if (Rank[i] != Rank[j])
return Rank[i] < Rank[j];
else
{
int x = (i+k <= len ? Rank[i+k] : -);
int y = (j+k <= len ? Rank[j+k] : -);
return x < y;
}
}
void build_sa()
{
for (int i = ; i <= len; i++)
{
sa[i] = i;
Rank[i] = (i < len ? s[i] : -);
}
for (k = ; k <= len; k *= )
{
sort (sa,sa+len+,cmp);
tmp[sa[]] = ;
for (int i = ; i <= len; i++)
{
tmp[sa[i]] = tmp[sa[i-]] + (cmp(sa[i-],sa[i])? : );
}
for (int i = ; i <= len; i++)
Rank[i] = tmp[i];
}
} void Get_lcp()
{
for (int i = ; i < len; i++)
Rank[sa[i]] = i;
int h = ;
lcp[] = ;
for (int i = ; i < len; i++)
{
int j = sa[Rank[i]-];
if (h > )
h--;
for (; h+i < len && h+j < len; h++)
if (s[i+h] != s[j+h])
break;
lcp[Rank[i]] = h;
}
}
bool isdigit(char &ch)
{
return ch >= '' && ch <= '';
}
int vec[maxn], board[maxn], tot;
int SUM[maxn];
int solve (int l, int r)
{
if (l > r)
return ;
int res ;
res = sum[r] - sum[l-];
res = ((res%mod)+mod)%mod;
res -= num[l-] * SUM[r-l+];
res = ((res%mod)+mod)%mod;
return ((res%mod)+mod)%mod;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int n;
SUM[] = ;
for (int i = ; i < maxn; i++)
{
SUM[i] = (SUM[i-] + ) * % mod;
}
while (~scanf ("%d", &n))
{
s = "\0";
tot = ;
memset(sum, , sizeof(sum));
memset(num, , sizeof(num));
for (int i = ; i < n; i++)
{
string tmp;
cin >> tmp;
s += tmp + "#";
}
len = s.size();
int val = ;
for (int i = ; i < len; i++)
{
if (s[i] != '#')
{
val = (val * + s[i] - '') % mod;
num[i] = val;
sum[i] = (sum[i-] + num[i]) % mod;
board[i] = tot;
}
if (s[i] == '#')
{
vec[tot++] = i;
num[i] = val;
sum[i] = sum[i-] + val;
}
}
build_sa();
Get_lcp();
int ans = ;
for (int i = ; i < len; i++)
{
int t1 = i + lcp[Rank[i]];
if (s[i] == '')
continue;
if (isdigit(s[i]) && i+lcp[Rank[i]] < vec[board[i]])
{
int t2 = vec[board[i]] -;
int ans1 = solve(i, t2);
int ans2 = solve(i , t1-);
ans = (ans + solve(i, t2) - solve(i, t1-)) % mod;
if (ans < )
ans += mod;
}
}
printf("%d\n", ans%mod);
}
return ;
}

HDU4436---str2int 后缀树组(12年天津区域赛)的更多相关文章

  1. 【BZOJ-1396&2865】识别子串&字符串识别 后缀自动机/后缀树组 + 线段树

    1396: 识别子串 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 312  Solved: 193[Submit][Status][Discuss] ...

  2. FZU 2137 奇异字符串 后缀树组+RMQ

    题目连接:http://acm.fzu.edu.cn/problem.php?pid=2137 题解: 枚举x位置,向左右延伸计算答案 如何计算答案:对字符串建立SA,那么对于想双延伸的长度L,假如有 ...

  3. SPOJ694 -- DISUBSTR 后缀树组求不相同的子串的个数

    DISUBSTR - Distinct Substrings   Given a string, we need to find the total number of its distinct su ...

  4. POJ3581---Sequence 后缀树组

    题意:n个数字组成的序列,第一个数字最大,,把序列分成3部分,每个部分分别翻转,输出翻转后字典序最小的序列.. 后缀数组变一下,,先求出 第一个分割的位置,,然后再求一次后缀数组,,求出第二个位置.. ...

  5. CF504E Misha and LCP on Tree(树链剖分+后缀树组)

    1A真舒服. 喜闻乐见的树链剖分+SA. 一个初步的想法就是用树链剖分,把两个字符串求出然后hash+二分求lcp...不存在的. 因为考虑到这个字符串是有序的,我们需要把每一条重链对应的字符串和这个 ...

  6. [hdu4436 str2int]后缀自动机SAM(或后缀数组SA)

    题意:给n个数字串,求它们的所有不包含前导0的不同子串的值之和 思路:把数字串拼接在一起,构造SAM,然后以每个状态的长度len作为特征值从小到大排序,从前往后处理每个状态,相当于按拓扑序在图上合并计 ...

  7. 【2012天津区域赛】部分题解 hdu4431—4441

    1001: 题意:给你13张麻将牌,问可以胡哪些张 思路: 枚举可能接到的牌,然后dfs判断能否胡 1002: 题意: 已知n,m 求 n的所有约数在m进制下的平方和 做法:队长用java高精度写的 ...

  8. ACM学习历程——HDU4472 Count(数学递推) (12年长春区域赛)

    Description Prof. Tigris is the head of an archaeological team who is currently in charge of an exca ...

  9. ACM学习历程——HDU4814 Golden Radio Base(数学递推) (12年成都区域赛)

    Description Golden ratio base (GRB) is a non-integer positional numeral system that uses the golden ...

随机推荐

  1. SVN在Android Studio中的配置

    在AndroidStudio中开发版本控制,除了Git就是SVN,和Eclipse不同Android Studio没有提供单独的插件,只能和SVN客户端关联使用,和Eclipse安装有很大区别,下面介 ...

  2. ipcs, ipcrm 命令

    ipcs命令 是linux/uinx上提供关于一些进程间通信方式的信息,包括共享内存,消息队列,信号 ipcs用法 ipcs -a  是默认的输出信息 打印出当前系统中所有的进程间通信方式的信息 ip ...

  3. C++库研究笔记——Linux下是否需要使用memory pool?

    Linux Slab分配器(一)--概述 Linux slab 分配器剖析 C++库研究笔记——内存池实现 做了一些测试:发现linux使用内存池与否没有明显差别,仅仅有2倍. Linux内存处理机制 ...

  4. 如何完全退出android应用程序

    当一个android应用程序包含多个activity时,要完全退出android应用程序,便要销毁掉所有的activity,下面是一种网上流传的比较经典完美的方法: 首先要定义一个继承Applicat ...

  5. Android组件系列----BroadcastReceiver广播接收器

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  6. spring-data-redis问题总结

    如何判断一个字符串是否是合法的long类型? 参考文档如下: http://www.oschina.net/question/59889_45179 spring-data-redis http:// ...

  7. maven项目,去除jar包中的不想要的依赖关系(Document root element "beans", must match DOCTYPE root "null". )

    maven dependencies中并不会删除 以下方法maven dependencies中并不会删除,可能程序引入的时候,会去掉这种依赖(猜的) 解释: 就是说项目中要用到某一个a.jar包,通 ...

  8. 【转载】Java StringBuffer与StringBuider

    本文转载微学苑java基础教程,原文地址链接:http://www.weixueyuan.net/view/6318.html String 的值是不可变的,每次对String的操作都会生成新的Str ...

  9. VS2013打包与部署

    近期做一个配置工具,完事了想打包一下:由于用的是VS2013:与之前的略有不同,简单的做了一下,在这里分享一下,直接看吧: 首先  是自己新建一个项目 ,我的WPF应用程序 第二步:右键解决方案添加新 ...

  10. Dapper基本增删改查

    说明: 1.在using语句块中不用dbConnection.Open(),因为Execute方法中会Open,并且在执行完成会Close. 2.在Ado.Net中要手动Open,在Using语句块中 ...