HDU 4436 (后缀自动机)
HDU 4436 str2int
Problem : 给若干个数字串,询问这些串的所有本质不同的子串转换成数字之后的和。
Solution : 首先将所有串丢进一个后缀自动机。由于这道题询问的是不同的子串之间的计数,不涉及子串的数目,因此考虑用后缀链即后缀自动机的nt转移数组来做。首先将所有节点进行按照距离大小进行基数排序,然后从小到大枚举每个节点的出边,假设当前点为u,转移到v,那么更新的状态为cnt[v] += cnt[u], sum[v] += sum[u] + cnt[u] * ch,cnt[u]表示的是到达当前节点的子串的数量,sum[u]表示的是该节点所表示的串的答案。
需要注意的是具有前导0的串对答案没有贡献。
#include <string>
#include <iostream>
using namespace std;
const int N = 200008;
const int mo = 2012;
struct Suffix_Automaton
{
	int nt[N][10], fail[N], a[N];
	int last, root, tot;
	int p, q, np, nq;
	int c[N], rk[N], cnt[N], sum[N];
	int newnode(int len)
	{
		for (int i = 0; i < 10; ++i) nt[tot][i] = -1;
		fail[tot] = -1; a[tot] = len;
		c[tot] = rk[tot] = cnt[tot] = sum[tot] = 0;
		return tot++;
	}
	void clear()
	{
		tot = 0;
		last = root = newnode(0);
	}
	void insert(int ch)
	{
		p = last; last = np = newnode(a[p] + 1);
		for (; ~p && nt[p][ch] == -1; p = fail[p]) nt[p][ch] = np;
	    if (p == -1) fail[np] =	root;
		else
		{
			q = nt[p][ch];
			if (a[p] + 1 == a[q]) fail[np] = q;
			else
			{
				nq = newnode(a[p] + 1);
				for (int i = 0; i < 10; ++i) nt[nq][i] = nt[q][i];
				fail[nq] = fail[q];
				fail[q] = fail[np] = nq;
				for (; ~p && nt[p][ch] == q; p = fail[p]) nt[p][ch] = nq;
			}
		}
	}
	void solve()
	{
		for (int i = 0; i < tot; ++i) c[a[i]]++;
		for (int i = 1; i < tot; ++i) c[i] += c[i - 1];
		for (int i = 0; i < tot; ++i) rk[--c[a[i]]] = i;
		cnt[root] = 1;
		for (int i = 0; i < tot; ++i)
		{
			int u = rk[i];
			for (int j = 0; j < 10; ++j)
				if (~nt[u][j])
				{
					if (i == 0 && j == 0) continue;
					int v = nt[u][j];
					cnt[v] += cnt[u ];
					sum[v] += sum[u] * 10 + j * cnt[u];
					sum[v] %= mo;
				}
		}
		int ans = 0;
		for (int i = 0; i < tot; ++i)
		{
			ans += sum[i];
			ans %= mo;
		}
		cout << ans << endl;
	}
}sam;
int main()
{
	cin.sync_with_stdio(0);
	int n;
	while (cin >> n)
	{
		string s;
		sam.clear();
		for (int i = 1; i <= n; ++i)
		{
			cin >> s;
			sam.last = 0;
			for (int j = 0, len = s.length(); j < len; ++j)
				sam.insert(s[j] - '0');
		}
		sam.solve();
	}
}
												
											HDU 4436 (后缀自动机)的更多相关文章
- str2int HDU - 4436 后缀自动机求子串信息
		
题意: 给出 n 个串,求出这 n 个串所有子串代表的数字的和. 题解; 首先可以把这些串构建后缀自动机(sam.last=1就好了), 因为后缀自动机上从 root走到的任意节点都是一个子串,所有可 ...
 - HDU 5442 后缀自动机(从环字符串选定一个位置 , 时针或顺时针走一遍,希望得到字典序最大)
		
http://acm.hdu.edu.cn/showproblem.php?pid=5442 题目大意: 给定一个字符串,可理解成环,然后选定一位置,逆时针或顺时针走一遍,希望得到字典序最大,如果同样 ...
 - HDU 4622 (后缀自动机)
		
HDU 4622 Reincarnation Problem : 给一个串S(n <= 2000), 有Q个询问(q <= 10000),每次询问一个区间内本质不同的串的个数. Solut ...
 - HDU 4416 (后缀自动机)
		
HDU 4416 Good Article Good sentence Problem : 给一个串S,和一些串T,询问S中有多少个子串没有在T中出现. Solution :首先对所有的T串建立后缀自 ...
 - HDU 5442 后缀自动机+kmp
		
题目大意: 给定一个字符串,可理解成环,然后选定一位置,逆时针或顺时针走一遍,希望得到字典序最大,如果同样大,希望找到起始位置最小的,如果还相同,就默认顺时针 比赛一直因为处理最小位置出错,一结束就想 ...
 - hdu 6208(后缀自动机、或者AC自动机
		
题意:给你n个字符串,问你是否存在一个字符串可以从中找到其他n-1个字符串. 思路:其实很简单,找到最长的那个字符串对他进行匹配,看是否能匹配到n-1个字符串. 可以用AC自动机或者后缀自动机做,但是 ...
 - Boring counting HDU - 3518 后缀自动机
		
题意: 对于给出的字符串S, 长度不超过1000, 求其中本质不同的子串的数量, 这些子串满足在字符串S中出现了至少不重合的2次 题解: 将串放入后缀自动机中然后求出每一个节点对应的子串为后缀的子串出 ...
 - Alice's Classified Message HDU - 5558  后缀自动机求某个后缀出现的最早位置
		
题意: 给定一个长度不超过 10W 的只包含小写字母的字符串,从下标 0 到 n−1.从下标 0 开始操作, 每次对于下标 pos查找下标 pos 开始的子串中最长的在其他地方出现过的长度,其他出现的 ...
 - 不在B中的A的子串数量 HDU - 4416 (后缀自动机模板题目)
		
题目: 给定一个字符串a,又给定一系列b字符串,求字符串a的子串不在b中出现的个数. 题解: 先将所有的查询串放入后缀自动机(每次将sam.last=1)(算出所有子串个数) 然后将母串放入后缀自动机 ...
 
随机推荐
- android开发哪些坑需要注意
			
同一个应用的JNI代码,不要轻易换NDK编译的版本,否则会有很多问题(主要是一些方法实现不一样,并且高版本对代码的检测更严格),比如r8没有问题,但到r9就有问题了,这是个大坑: Android的JN ...
 - HDU 4465 Candy (数学期望)
			
题意:有两个盒子各有n个糖(n<=2*105),每天随机选1个(概率分别为p,1-p),然后吃掉一颗糖.直到有一天打开盒子一看,这个盒子没有糖了.输入n,p,求此时另一个盒子里糖的个数的数学期望 ...
 - uva1352 Colored Cubes LA3401
			
白书第一章例题8 好麻烦! 正方体每面编号为0-5,那么根据顶点和正面,就能确定形态.一共6*4=24种形态. P[i]表示编号i所在位置.比如P[1]=3,表示第二面转到了第四面. 就可以表示出所有 ...
 - 指针-动态开点&合并线段树
			
一个知识点不在一道题里说是没有灵魂的 线段树是用来处理区间信息的咯 但是往往因为需要4倍空间让许多人退却,而动态开点的线段树就非常棒 仿佛只用2倍就可以咯 指针保存位置,即节点信息,是很舒适的,所以用 ...
 - STL || Gym 101653U Top 25
			
一组字符串给出两种排列方式, 求最小分成多少组 如 A A B C C D D B E E 则分成3组 A B C D E 即为1 3 1 #include < ...
 - TWaver3D直线、曲线、曲面的绘制
			
插播一则广告(长期有效) TWaver需要在武汉招JavaScript工程师若干 要求:对前端技术(JavasScript.HTML.CSS),对可视化技术(Canvas.WebGL)有浓厚的兴趣 基 ...
 - LinkedHashMap/HashMap(数҉据҉缓҉存҉准҉备҉)
			
顾名思义LinkedHashMap是比HashMap多了一个链表的结构.与HashMap相比LinkedHashMap维护的是一个具有双重链表的HashMap,LinkedHashMap支持2中排序一 ...
 - 【转载】WampServer图标显示红色后变成橙色怎么解决
			
WampServer就是Windows Apache Mysql PHP集成安装环境,即在window下的apache.php和mysql的服务器软件. 工具/原料 WampServer 方法/步 ...
 - InnoDB INFORMATION_SCHEMA Temporary Table Info Table
			
InnoDB INFORMATION_SCHEMA Temporary Table Info Table INNODB_TEMP_TABLE_INFO提供有关InnoDB实例中当前活动的用户创建的In ...
 - 深入Linux内核架构——进程虚拟内存
			
逆向映射(reverse mapping)技术有助于从虚拟内存页跟踪到对应的物理内存页: 缺页处理(page fault handling)允许从块设备按需读取数据填充虚拟地址空间. 一.简介 用户虚 ...