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. 国内三大PT(Private Tracker)站分析

    除这一行外,下面全部内容都是转载.出处不明. 国内三大PT(Private Tracker)站分析 先郑重的声明一下:本文以下的内容所有是复制粘贴的,不代表老夫的观点. 事实上内容我也没细致看. 贴这 ...

  2. apk文件伪装zip64格式案例

    软件样本:http://files.cnblogs.com/files/mmmmar/FMRMemoryCleaner.apk 在论坛看在网友求助把一个小的app去广告,下载一看是清理内存的,刚开始让 ...

  3. UITableView的编辑(插入、删除、移动)

    先说两个方法beginUpdates和endUpdates,几点注意事项: 一般我们把行.块的插入.删除.移动写在由这两个方法组成的函数块中.如果你不是在这两个函数组成的块中调用插入.删除.移动方法, ...

  4. C#txt文件读写基本操作

    string strFileName=@"C:\Users\Administrator\Desktop\记事2.txt"; //判断是否存在 if (File.Exists(str ...

  5. 【网络流#9】POJ 2135 Farm Tour 最小费用流 - 《挑战程序设计竞赛》例题

    [题意]给出一张无向图,从1开始到n,求两条没有公共边的最短路,使得路程总和最小 每条边的权值设为费用,最大流量设为1,然后就是从源点到汇点流量为2的最小费用流. 因为是规定了流量,新建一个源点和一个 ...

  6. 【iOS之轮播视图、自定义UIPageControl】

    基于UISrollView实现的无限循环轮播视图. 实现的思路:使用三个UIImageView不断循环利用,始终将最中间一个View显示在UIScrolView的contentSize上,每次滚动后, ...

  7. Vitamio 多媒体框架 介绍

    功能 Vitamio 是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染.Vitamio 凭借其简洁易用的 API 接口赢得了全球众多开发者的青睐.到目前 ...

  8. spring07 JDBC

    1.创建对应的数据库 2.在MyEclipse中创建项目  引入需要的jar包 3.创建数据访问层 public interface StudentDao { //新增学生 int addStuden ...

  9. 安装Microsoft oneDrive(原skyDrive)

    oneDrive下载地址:https://onedrive.live.com/about/zh-cn/download/ 安装时报错:Error 0x80040ca0 解决方案:关闭安装程序,按下面的 ...

  10. Quartz.net使用记录

    1.引入dll文件: nuget控制台:安装quartz:Install-Package Quartz 安装log4net:Install-Package log4net,这里使用log4net记录一 ...