摘要: 还是统计串问题,只是分成了同一种串允许互相覆盖和不允许互相覆盖两种情况。 对于允许互相覆盖的情况,就是模版了。对于不允许覆盖的情况,只要记录下该串最后一次出现并且被统计的位置即可,能统计的条件是lasp[id]+len[id]<=pos。#include <string.h>#include <stdio.h>#define MAXL 600001#define MAXN 100001#define INF 0x3fffffffchar s[MAXN],s1[10];int n,type,stp[MAXN],sps[MAXN];int next[MAXL][26] 阅读全文
posted @ 2012-08-07 17:07 Burn_E 阅读(246) 评论(0) 推荐(0)
摘要: 给出一个DNA串以及若干个带有疾病的串,问至少要改变DNA串中的几个字符,才能让它不携带病毒串。其实还是不包含若干子串的问题,可以转化为走一条不包含病毒串的路径,这条路径组成的串和给出DNA串最少相差几个字符,这样就很容易想到DP方程 d[i][j]一开始初始化为无穷大,x是j的父亲节点,也就是说存在next[x][p]=j,一般都是从前向后刷表的。flag表示这一位和DNA串中的对应字符是否相等,相等时为0,不相等时为1。 注意在走的过程中不要走到危险节点上去。#include <string.h>#include <stdio.h>#define MAXN 1001 阅读全文
posted @ 2012-08-07 15:38 Burn_E 阅读(305) 评论(0) 推荐(0)
摘要: 给出M个单词,问长度为N的包含不少于K个单词的字符串一共有多少个。到目前为止做的自动机的题目好像都是差不多样子。。都是包含不包含单词之类的。。 这题用d[i][j][k]表示第i步走到字符j包含了单词集合k,因为一共只有10个单词,可以用二进制压缩状态表示这个集合。注意在建立trie图时要合并节点和它的fail节点的状态,一开始没想到这个WA了一次。状态转移方程为 不加优化的代码交上去时间接近TLE。。。于是改成了滚动数组,并用for循环清0,还是要跑360ms左右。这相对于1s的时限还是很慢的。。。于是点了下Statistic,发现大家都是跑了好几百ms。。。。#include ... 阅读全文
posted @ 2012-08-07 13:15 Burn_E 阅读(207) 评论(0) 推荐(0)
摘要: 应该算是最基础的AC自动机DP了吧。。 跟前面做的两道用矩阵加速的AC自动机题目意思差不多,都是求不包含给定单词的单词数。区别就是给定单词较多,需要的字符串比较短,然后结果不取模,要用到高精度。 trie图中大约有50*10个节点,如果建立矩阵用矩阵加速无论是时间复杂度还是空间复杂度都是会超的(时间大约是500^3*log(50),空间是500^2*高精度数组)。所以这里要用到DP了,用dp[i][j]表示第i步在第j个节点的方法数。flag[k]=0表示不是非法节点,son是k的儿子节点的集合。 一开始爆空间了,POJ真心抠啊,这题就给了10M内存,后来高精度里面用char存,... 阅读全文
posted @ 2012-08-07 10:26 Burn_E 阅读(258) 评论(0) 推荐(0)
摘要: 就是POJ2778的加强版,思路是一样的。 出现过给定的单词的单词数=总单词数-未出现过给定单词的单词数,前者等于26^1+26^2+26^3....26^l,后者等于Mat^1+Mat^2+..Mat^l,这里的Mat是根据能走的字符之间的路径数建立出来的邻接矩阵。两者求出来一减就可以了,对2^64取模可以忽略,直接用unsigned long long做,忽视溢出就等于取模了,注意减法最后结果可能小于0,要加2^64变成正数。 求a^1+..a^n用一次二分就可以,建议这种二分都写成非递归的,效率比较高而且不会有爆栈的隐患。 #include <stdio.h>#include 阅读全文
posted @ 2012-08-07 10:04 Burn_E 阅读(245) 评论(0) 推荐(0)