摘要: 题意:给一个正整数序列,记为a1,a2,……an,现需找i,j,使得i<j,并且ai与aj之间的数均比ai大,均比aj小,求符合上述条件的i与j,使得j-i的最大。分析:易知序列中的最小值比其他所有数都小,最大值比其他所有数都大,所以可以现找到最小的数与最大的数的位置,记为i,j,若i<j,则区间[i,j]内符合上述条件的最值就是j-i,然后递归求解左右区间[1,i-1],[j+1,n],若i>j,则将区间分为三段递归求解,[1,j],[j+1,i-1],[i,n]。递归边界为区间左端点>=区间右端点时返回-1。每次求区间的最大与最小值的位置可以用线段树解决。View 阅读全文
posted @ 2012-08-03 23:59 BeatLJ 阅读(268) 评论(0) 推荐(0) 编辑
摘要: 题意:给一棵含n个结点的树,现要查询从a到b的路径中是否包含c,共q次查询。1=<n,q<=100000分析:由于在树中从一个结点走到另一个结点的路径是唯一的,其实说的这条路径就是最短路径,然后问题转化为判断一个点是否为在一条最短路径上,此时就不难想到这个这个判断条件d(a,c)+d(c,b)=d(a,b),问题就转化为查询树中2个结点之间的距离,这个可以用LCA来做(参考上一篇),考虑到n和q都比较大,所以用离线LCA.View Code #include <stdio.h>#include <string.h>#define N 100010#defin 阅读全文
posted @ 2012-08-03 23:27 BeatLJ 阅读(231) 评论(0) 推荐(0) 编辑
摘要: 题意:给一棵带权重的树,共有k个查询,每次查询树中2个结点的距离。结点数n最大为40000,k最大10000分析:首先我们将无根树转为有根树,可以在O(n)时间内得到每个结点到根结点的距离。由于在树中从一个结点走到另一个结点的路径是唯一的,所以a到b的路径一定经过lca(a,b),设lca(a,b)=c。此时不难发现d(a,b)=d(a,root)+d(b,root)-2*d(c,root)。先在问题就是如何快速求LCA,由于结点数目比较大,查询比较多,所以用在线算法会超时。这里用的是tarjan离线算法,时间复杂度为O(n+k)。View Code #include <stdio.h& 阅读全文
posted @ 2012-08-03 23:15 BeatLJ 阅读(939) 评论(0) 推荐(0) 编辑
摘要: 模型:给定一个整数矩阵,查询某个子矩阵中的最大数与最小数之差。N最大为250,查询数K最大为100000我的做法:用线段树求出要查询的子矩阵每一行的最大与最小,然后在列方向上统计子矩阵的最大与最小。有点暴力,跑了800+ms。View Code #include <stdio.h>#include <string.h>#define N 255#define MAX(a,b) ((a)>(b)?(a):(b))#define MIN(a,b) ((a)<(b)?(a):(b))int n,b,k,D;int max[N][4*N];int min[N][4* 阅读全文
posted @ 2012-08-03 17:40 BeatLJ 阅读(253) 评论(0) 推荐(0) 编辑
摘要: 题目大意:给你一个含n个整数的不下降序列,现需查询某个区间内出现次数最多的数,对于每次查询输出出现最多的次数即可。分析:由于序列是有序的,所以一个数如果在序列中出现多次,那么一定是连续出现的,这样的话就可以把问题转化为区间染色问题,查询的是某个区间中最长的同色区间的长度。区间保存的关键信息有,区间内的某数出现的最大次数,区间最左边的数及其在该区间内出现的次数,区间最右边的数及其在该区间内出现的次数。保存左右两边的信息为为了更新父结点,因为父结点的最大answer可能由左儿子和右儿子合并得到。这题我一开始用堆实现的线段树,发现了很多问题,用堆实现的线段树中有很多没有用到的空间,处理不好会造成结果 阅读全文
posted @ 2012-08-03 17:34 BeatLJ 阅读(224) 评论(0) 推荐(0) 编辑