摘要: a^b,假如a和b分别是10000000 10000000,我们知道计算机是无法存储这样大的数的。看来直接计算,然后取前N位和后N位,是不可能的了。先来看后N位如何计算,假设N==3。那么不管a实际上有多大,我们的计算结果实际上只和a的后3位有关,也就是说第四位开始对我们的答案是没有影响的,能理解么?所以我们先让a对1000取模,然后利用快速幂算法求出a^b次方,过程中别忘记了对1000取模。再来看前N位如何计算,同样假设N==3.假设a^b==c。那么我们对c取一个log10,得到d。d肯定是一个浮点数,我们先看d的整数部分,10^(d的整数部分)等于100000....(d个0),好了,注 阅读全文
posted @ 2012-10-09 13:03 Accept 阅读(1506) 评论(0) 推荐(1) 编辑
摘要: 题意:给你一个集合,集合里没有重复元素。集合可以添加元素,也可以删除元素(前提是集合里有),另外还有一个询问操作,问集合里最小的差值是多少(只有一个元素的时候询问无效)例如,集合开始的时候有1 7两个元素,那么最小差值就是6。当再添加一个新的元素3,集合就变成了1 3 7,那么最小差值就是2。解法:对于每一个区间线段,我们给它3个属性,最小值minf,最大值maxf,以及最小差值deff。从下而上,我们很容易可以看出,某一个线段 i 的最小值为min(left_child[i].minf,right_child[i].minf) 最大值... 阅读全文
posted @ 2012-10-09 12:24 Accept 阅读(802) 评论(0) 推荐(0) 编辑
摘要: http://codewaysky.sinaapp.com/problem.php?id=1056这题和奶牛浴场略有区别,奶牛浴场只需要求出最大子矩形,而这题要求的是最大权重子矩形,不一定要最大的面积,但要最大的权重和思路是先求出每个最大子矩形,然后求出每个矩形的左上点和右下点,然后用二维数转数组进行求和,保存最优解View Code 1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<stdio.h> 5 #include<memory.h> 阅读全文
posted @ 2012-09-30 14:55 Accept 阅读(775) 评论(0) 推荐(0) 编辑
摘要: http://codewaysky.sinaapp.com/problem.php?id=1057提交这题的OJ比较少,可以在这里提交根据王知昆的论文里说的,解决这种问题通常有两种方法。这里我用的第二种方法。什么都不懂的,先看论文http://wenku.baidu.com/view/728cd5126edb6f1aff001fbb.html具体的没啥好说的,根据论文里说的实现以下就是了,详细注释看codeView Code 1 #include<iostream> 2 #include<string> 3 #include<stdio.h> 4 #incl 阅读全文
posted @ 2012-09-30 13:59 Accept 阅读(1219) 评论(0) 推荐(0) 编辑
摘要: 这题的意思是,给你n个长度不超过5的字符串,求有多少个长度为至少为L的字符串,里面至少包含n个字符串中的一个。这题和求DNA片段的差不多啦,只不过L的条件有点变化。假设矩阵A里储存着字符间的可行转移,那么A^L就代表了长度为L的不包含n个字符串中任何一个的个数。最终的答案就是26^1+26^2+......+26^L减去A^1+A^2+....+A^L矩阵A可以用ac自动机维护一个跳转表得到。接下来就是考虑如何快速的求得A^1+A^2+....+A^L了。根据矩阵的性质|A, 1| |A^n, 1+A^1+A^2+....+A^(n-1)||0, 1| 的n次方等于|0, 1|所以我们只需要将 阅读全文
posted @ 2012-09-14 14:06 Accept 阅读(1091) 评论(0) 推荐(0) 编辑
摘要: 感谢http://blog.henix.info/blog/poj-2778-aho-corasick-dp.html给的灵感看数据规模,很容易想到用矩阵求解,关键是如何得到原始矩阵。上面连接博客中的方法给力,在AC自动机上确定出每一个点的跳转点,即jump数组,表示该点可以跳转到的点。利用每个点的jump数组,我们就可以确定出一张跳转表,也即时我们需要的原始矩阵。对每个点,如果它不是病毒片段的结尾,那么它便是安全的。我们很容易可以理解,安全点到安全点之间的跳转,总是安全的。给每个安全点一个编号,构建一个矩阵a[][]。那么a[i][j]就表示从第j个安全点能够跳转到第i个安全点的数量。将这个 阅读全文
posted @ 2012-09-12 15:45 Accept 阅读(587) 评论(0) 推荐(0) 编辑
摘要: http://blog.henix.info/blog/trie-aho-corasick.html这个博客说的很清楚了。自己实现了个,留个模版View Code 1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 using namespace std; 5 6 struct node 7 { 8 struct node *fail; 9 struct node *next[26]; 10 int cnt; 11 node() 12 { 13 ... 阅读全文
posted @ 2012-09-11 22:21 Accept 阅读(352) 评论(0) 推荐(0) 编辑
摘要: 由于给出的数太大了,所以我们将两个数A,B拆成了N个数相乘和M个数相乘的形式。N,M<=1000,拆成的数<=1000000000。是不是够大?最终的结果最多保留9位输出。例如:3358572 83391967 82350229961 1091444 8863输出为:000012028根据欧拉公式,我们可以将任何一个数表示成如下形式:n=p1^x1*p2^x2*p3^x3.......*pm^xm;如果将A和B分别表示成A = p1^a1 * p2^a2 * … * pn^anB = p1^b1 * p2^b2 * … * pn^bn其中p1,p2....都是素数,a1,a2... 阅读全文
posted @ 2012-08-31 14:45 Accept 阅读(3281) 评论(2) 推荐(0) 编辑
摘要: 多项式插值取模哈希标记法是用来标记字符串的一种哈希标记法,能够快速,较为精确的进行哈希标记。在该方法中,字符串被看做是一种37进制的数。对于一个字符串,可以用以下方法计算它的哈希值LL p=0; //计算hash值用for(j=0;j<len;j++) p=p*T+(a[j]-'a'+1);其中T=37。我们可以发现,如果一个串的长度上千上万,那么这个hash值就会很大。这时候,我们需要将hash值进行分类,也就是取模,我们设定一个常数,假设这个常数是H,那么所有的hash值将会被分类成H类。分别是0+H,0+2*H......0+N*H1+H,1+2*H,1+3*H.. 阅读全文
posted @ 2012-08-30 16:15 Accept 阅读(1456) 评论(0) 推荐(0) 编辑
摘要: 题意: 你在一条布满地雷的道路上,开始在坐标1。每次有概率P向前走一步,有概率1-P向前走两步。道中路某几个点上会有地雷,问你安全通过的概率。地雷数N<=10,坐标范围在100000000内。假设dp[i]表示安全走到i点的概率,那么dp[i]=P*dp[i-1]+(1-P)*dp[i-2]。很简单的一个转移,可是偏偏坐标范围太大了。直接递推爆内存,而且肯定也会超时。我们换一个思路,假设x[i]表示第i个地雷的坐标。对于任何两个地雷x[i]~~x[i-1]+1之间,只会有一个地雷,那就是x[i]。我们安全通过该段的概率等于1 减去猜到x[i]的概率。也就是说,我们将n个地雷分成n段分别处 阅读全文
posted @ 2012-08-29 12:47 Accept 阅读(351) 评论(0) 推荐(0) 编辑