上一页 1 2 3 4 5 6 ··· 9 下一页
摘要: 和poj 1625一样,不同的是长度变长了 先考虑另外一个问题,给你一个有向图,从某个点出发走n步到其他任意点,问不同的走法。 对这个问题构造一个矩阵,matrix[i][j]表示从i到j有几条边,然后这个矩阵自乘n次就是答案。 再说这个问题, Trie图本身就是一个有向图,那么一个长度为n的字符串相当于从根节点沿着边走n步。。。所以和上面那个问题一样。。构造矩阵的时候要注意边不能有非法节点。 可以在构造矩阵时去掉非法节点的行和列来优化。。(这里我没去掉。。。 1 #include 2 #include 3 #include 4 #include 5 using name... 阅读全文
posted @ 2013-08-09 12:08 silver__bullet 阅读(937) 评论(2) 推荐(0) 编辑
摘要: 题意: 给你一个字典,还有一些非法串,利用字典中的字符组成长度为m的不含非法串的字符串,求方案数。解法: 坑了我一整天我擦。。。。 因为自动机本身就是一个状态转移图,所以在上面进行DP很好理解,dp[i][j]记录长度为i并且走到DFA中j节点的方案数。。 需要注意的是非法节点是不能走的,在建Trie图的时候也要注意,如果当前节点的fail节点是非法的,那么这个点也是非法的,因为这个串包含了某个非法串。。。 1 #include 2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 con... 阅读全文
posted @ 2013-08-09 09:59 silver__bullet 阅读(433) 评论(0) 推荐(0) 编辑
摘要: 题意: 给一个1e5长只有小写字母的串,1e5个询问,问某个串在可以重叠或者不可以重叠的条件下最大匹配数。解法: 最开始的时候在Trie的每个节点把所有出现的单词编号全塞到vector里,结果TLE到死。其实如果在插入的时候,以同一个节点作为终止节点的只有那一个。。所以对一个串只插入一次就行,然后自动机匹配的时候分别统计可以重叠和不可以重叠的匹配数。 可以重叠的匹配只要在自动机上跑就行,对于不可以重叠的,记录一下上次匹配的位置,然后判断一下是否满足条件就行。。 字符串判重的时候我写了个双重hash。。。 1 #include 2 #include 3 #include 4 #i... 阅读全文
posted @ 2013-08-08 00:02 silver__bullet 阅读(320) 评论(0) 推荐(0) 编辑
摘要: 解法: 在对树的dfs同时维护两颗线段树,记录到达当前节点经过左路径和右路径上的权值,然后注意回退的时候要删除。。。 1 #include 2 #include 3 #include 4 #include 5 #pragma comment(linker, "/STACK:102400000,102400000") 6 using namespace std; 7 #define lson l,m,nG[N]; 15 vectorV[N]; 16 int w[N]; 17 pairans[N]; 18 struct segtree{ 19 int s[N>1; 27 阅读全文
posted @ 2013-07-31 11:13 silver__bullet 阅读(396) 评论(5) 推荐(1) 编辑
摘要: 解法: 假设n分解因式之后的形式是n = a1 ^ b1 * a2 ^ b2 *...*an ^ bn 它的因子个数就是(b1+1)*(b2+1)*...*(bn+1) 因子和是(1+a1 ^ 1+..+a1 ^ b1)*(1 + a2 ^ 1 +..+a2 ^ b2 )*..*(1 + an ^ 1 + ... +an ^bn) 所以因子个数为素数的条件就是只有一个素因子并且b1 + 1为素数; 因子和为素数的条件就是只有一个素因子并且(1 + a1 ^ 1+..+a 1 ^ b1)为素数 接下来要判断因子积是不是完全平方数,因为因子都是成对出现的 i * n / i == ... 阅读全文
posted @ 2013-07-31 11:10 silver__bullet 阅读(385) 评论(0) 推荐(0) 编辑
摘要: 解法: 对于第二个串,循环移动能得到的字典序最小的串,可以直接用最小表示法搞定。 然后用最小表示的第二个串和第一个串做两次扩展KMP,一次正常求,另外一次将两个串都反转一下,然后扫一遍ex[]数组 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N = (int)2e6+10; 6 char a[N],b[N],c[N]; 7 int next[N],exa[N],exb[N]; 8 void getnext(cha 阅读全文
posted @ 2013-06-17 21:03 silver__bullet 阅读(343) 评论(0) 推荐(0) 编辑
摘要: 这题和这个是一样的,唯一的不同是内存限制变小了今天学到了一种函数式线段树成段更新时节约内存的办法 。。。先考虑朴素的仅支持成段加减的线段树,我们可以用方式解决:1.正常的懒惰标记,当访问到带有懒惰标记节点的子区间时将标记下传;2.不用下传的懒惰标记,我们用一个标记来记录当前节点的整段区间被累加了多少,当询问的时候我们在从根节点走到目标结点的过程中不断累加所经过节点上的标记值。。。基于这两种思想,就有了函数式线段树的两种实现方式,第一种在pushdown的过程中会产生大量的结点,而第二种没有pushdown的过程,不会新建过多的节点 1 #include<cstdio> 2 #inc 阅读全文
posted @ 2013-06-05 21:38 silver__bullet 阅读(954) 评论(0) 推荐(0) 编辑
摘要: 题意: 带询问历史版本的线段树>_<解法: 主席树的成段更新,除了线段树成段更新的懒惰标记之外还要用一个懒惰标记来记录当前节点和其子节点是否是同一个版本的,如果不是的话,在pushdown的过程中要新建两个新节点,别的没什么了>_< p.s.主席树的内存消耗真是叹为观止。。。hdu4348徘徊在MLE和RE之间。。。 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 阅读全文
posted @ 2013-06-05 07:31 silver__bullet 阅读(473) 评论(0) 推荐(1) 编辑
摘要: 题意: 求某段区间内不同元素之和。解法: 离线处理,将待询问区间按照右端点排序,然后依次将元素插入到线段树中,为了保证求得的结果都是不同元素之和,我们需要保证同一时刻某个元素在线段树中只能出现一次,如果之前插入了,那就先删除再在新位置插入。 p.s.这题函数式线段树应该可以在线做,但是暂时没想到>_< 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef lon 阅读全文
posted @ 2013-06-03 21:44 silver__bullet 阅读(145) 评论(0) 推荐(0) 编辑
摘要: 题意:无修改的区间第k小问题。p.s.终于能用三种方法搞定这道题了,开心~ 划分树的方法喜闻乐见; 线段树套平衡树然后二分枚举答案,写起来比较麻烦; 今天刚刚想明白函数式线段树>_<,发现写这个还挺方便; 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N = (int)3e6+10; 6 const int maxn = (int)1e5; 7 int lson[N],rson[N],sum[N]; 8 阅读全文
posted @ 2013-06-03 14:36 silver__bullet 阅读(196) 评论(0) 推荐(0) 编辑
上一页 1 2 3 4 5 6 ··· 9 下一页