HDU4436---str2int 后缀树组(12年天津区域赛)
str2int
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1568 Accepted Submission(s): 540
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.
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.
101
123
09
000
1234567890
题意: 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年天津区域赛)的更多相关文章
- 【BZOJ-1396&2865】识别子串&字符串识别 后缀自动机/后缀树组 + 线段树
1396: 识别子串 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 312 Solved: 193[Submit][Status][Discuss] ...
- FZU 2137 奇异字符串 后缀树组+RMQ
题目连接:http://acm.fzu.edu.cn/problem.php?pid=2137 题解: 枚举x位置,向左右延伸计算答案 如何计算答案:对字符串建立SA,那么对于想双延伸的长度L,假如有 ...
- SPOJ694 -- DISUBSTR 后缀树组求不相同的子串的个数
DISUBSTR - Distinct Substrings Given a string, we need to find the total number of its distinct su ...
- POJ3581---Sequence 后缀树组
题意:n个数字组成的序列,第一个数字最大,,把序列分成3部分,每个部分分别翻转,输出翻转后字典序最小的序列.. 后缀数组变一下,,先求出 第一个分割的位置,,然后再求一次后缀数组,,求出第二个位置.. ...
- CF504E Misha and LCP on Tree(树链剖分+后缀树组)
1A真舒服. 喜闻乐见的树链剖分+SA. 一个初步的想法就是用树链剖分,把两个字符串求出然后hash+二分求lcp...不存在的. 因为考虑到这个字符串是有序的,我们需要把每一条重链对应的字符串和这个 ...
- [hdu4436 str2int]后缀自动机SAM(或后缀数组SA)
题意:给n个数字串,求它们的所有不包含前导0的不同子串的值之和 思路:把数字串拼接在一起,构造SAM,然后以每个状态的长度len作为特征值从小到大排序,从前往后处理每个状态,相当于按拓扑序在图上合并计 ...
- 【2012天津区域赛】部分题解 hdu4431—4441
1001: 题意:给你13张麻将牌,问可以胡哪些张 思路: 枚举可能接到的牌,然后dfs判断能否胡 1002: 题意: 已知n,m 求 n的所有约数在m进制下的平方和 做法:队长用java高精度写的 ...
- ACM学习历程——HDU4472 Count(数学递推) (12年长春区域赛)
Description Prof. Tigris is the head of an archaeological team who is currently in charge of an exca ...
- ACM学习历程——HDU4814 Golden Radio Base(数学递推) (12年成都区域赛)
Description Golden ratio base (GRB) is a non-integer positional numeral system that uses the golden ...
随机推荐
- QT5: QApplication, no such file or directory
In QT5, when I use this: #include<QApplication>, QT tells :no such file or directory, even tho ...
- hdu 3631 Shortest Path(Floyd)
题目链接:pid=3631" style="font-size:18px">http://acm.hdu.edu.cn/showproblem.php?pid=36 ...
- 桶排序与基数排序代码(JAVA)
桶排序 publicstaticvoid bucketSort(int[] a,int max){ int[] buckets; if(a==null || m ...
- 布局动画 LayoutAnimation
简介 http://blog.csdn.net/pipisky2006/article/details/8317091 补间动画只能对一个控件使用,如果要对某一组控件播放一样的动画的话,可以考虑lay ...
- SpringMVC04controller中定义多个方法
public class MyController extends MultiActionController { // 新增 方法修饰符要是public public ModelAndView ad ...
- 更加详细的Log4net的配置
请转到周金桥的文章 http://blog.csdn.net/zhoufoxcn/article/details/6029021
- Myeclipse笔记
1. 自动提示:窗口->首选项->Java->编辑器->内容辅助->自动激活,在下面的“Java的自动激活触发器里面填上“.abcdefghijklmnopqrstuv ...
- 无法连接vCenter Server清单https://IP:10443
VMware vCenter Server服务器安装系统的时候使用一个IP,安装完VMware vCenter后来更换了另外一个IP,当使用vSphere Web Client登陆VMware vCe ...
- JavaAppArguments.java程序的更改
此程序模仿JvaAppArgyments.java编写,从命令行接受多个数字,求和之后输出结果. 设计思想:命令行参数都是字符串,可以考虑用 Integer.parseInt(args[]) ...
- 几种破解MySQL root密码的几种方法:
几种破解MySQL root密码的几种方法: 方法一 使用phpmyadmin,这是最简单的了,修改mysql库的user表,不过别忘了使用PASSWord函数. 方法二 使用mysqladmin,这 ...