11 2011 档案

摘要:http://poj.org/problem?id=2886恩,分糖果,快乐的童年啊!题目意思大概n个小孩围成一个圈,每个小孩手里有张卡片,记录着一个数字。开始从第k个孩子,该孩子离开圈子,然后告诉别人他手里的数字,接下来便从位于该孩子的位置加上孩子手中的数字的孩子开始,直到所有的孩子都离开了圈子,游戏便结束。每个跳出圈子的孩子都能得到一定的糖果,数目是他跳出圈子的顺序数的因子数之和。 例如第6个跳出的孩子能得到(1,2,3,6)四个糖果。这个游戏,其实和猴子选大王是一样的!只要注意好求解相对位置即可,所谓相对位置,例如:a,b,c,d四个人,a对应1,b对应2,c对应3,d对应4.但是当b不 阅读全文
posted @ 2011-11-14 21:12 Accept 阅读(499) 评论(0) 推荐(1) 编辑
摘要:http://poj.org/problem?id=3145Harmony Forever。。。多吹牛B啊。这题巧妙的运用了鸽笼原理,什么是鸽笼原理?鸽笼原理就是给你N+1个数,则必定至少有两个数的余数是相同的!解决这题的时候,我们先用RMQ的方法求出每一段的最小值,这是容易做到的。这题的数据范围是500000,也就是说最多会有500000个叶子节点,当该叶子节点的值为inf的时候,表示这里没有值。当它的值等于它的位置的时候,表示它有值,例如:集合[3,4,5]在线段树中叶子节点中的表示为 [inf,inf,inf,3,4,5],前面三个inf分别表示0位,1位和2位询问的时候,假设我们要求的 阅读全文
posted @ 2011-11-14 20:06 Accept 阅读(381) 评论(0) 推荐(0) 编辑
摘要:http://poj.org/problem?id=2828灰常有趣的一道逆序思维题目,并且题目掐的很死,用链表什么的,统统tle如何逆序思维?假设数据如下:40 771 511 332 69我们从后向前解题,开始是第四个人,他的pos==2,可是他前面分明还有3个人,也就是说,他必须插一个人的队才有可能达到他要达到的位置再看第三个人,他的pos==1,他前面还有两人,他也需要插一个队再看第二个人,他的pos==1,前面也只有一个人,1-1==0,他不需要插队第一个人,0-0==0,也不需要插队了最终队序是:77 33 69 51我们用线段树加快插队速度,如何做?很简单,定义一个left表示该 阅读全文
posted @ 2011-11-14 11:14 Accept 阅读(217) 评论(0) 推荐(0) 编辑
摘要:http://poj.org/problem?id=2482A了这题后,我就在想,是不是ACMER都找不到女朋友.....这题看似很新颖,其实就是求线段树区间最值。所谓区间最值,其实就是和RMQ差不多,只不过RMQ是以点为单位,而这个是以区间为单位。怎么扯到区间最值了呢?因为每一颗星星,它都有一个亮度,假设这个星星现在正在最左边,那么它的亮度将会影响到向右W的范围。也就是说[star.x,star.x+W]这个区间都会因为这个亮度的影响而加上这个亮度值,最后求一个[x,x+W]的区间,并且该区间的亮度最大,这就是区间最值!方法和RMQ一样,只是不是更新到节点,而是更新到相应线段即可!这里还要注 阅读全文
posted @ 2011-11-14 10:50 Accept 阅读(261) 评论(0) 推荐(0) 编辑
摘要:http://poj.org/problem?id=3225这题很有意思,对于[0,65535]这么一个区间,初始值为0,问最后为连续1的子区间有哪些。很有趣的是,这题涉及到了开区间和闭区间,即() 和 [] 。确是比较棘手!解决的办法是将所给的数据范围乘以2,然后根据给的是开区间或则是闭区间修改数据,例如:给你(2,3]这样的数据,如何处理呢?我们将范围乘以2,得到(4,6],然后,如果左边是开区间,则将4加1,得到5,同理,如果右边是开区间,则将6减去一个1。为什么这样做呢? 看看,因为数据乘以2后,得到的结果一定是偶数,而偶数加一减一后,肯定得到奇数。也就是说,如果最后得到的数据是偶数, 阅读全文
posted @ 2011-11-14 10:17 Accept 阅读(250) 评论(0) 推荐(0) 编辑
摘要:http://poj.org/problem?id=1436这道题最终就是问,两两可见的三条线段组有多少组。所谓两两可见,指的是某一条横线可以连接到两条线段,并且中途不会碰到其他线段。很显然又是一道区间染色的题目嘛,关于区间染色的解法,不多说了,这里说关键的!这题就sample来说,按它给的数据来建树的话,最右边的和最左边的是无法触碰到一起的,因为第二根线段和第三根线段之间只留下了[2,3]这样的小缝隙,而这样的小缝隙在线段树建树的过程中,是会被二分忽略掉的。看图上面黑色的,就是题目所给的sample所对应的坐标系上的图样,而下面的红色的,就是上面的黑色的在线段树中所对应的图样。很显然最右边的 阅读全文
posted @ 2011-11-13 15:50 Accept 阅读(233) 评论(0) 推荐(0) 编辑
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1828线段树求解重叠矩形周长。这个比求并面积交面积难度大一些,要多想想才能明白回忆求并面积的时候的第二种方法,利用线段树树形dp出可以与下一个将要插入的线段去构成并面积的最大y坐标长度,即tree[1].len;然后求并面积的时候,只需要将tree[i].len*(line[i+1].x-line[i].x)即可。想一想,并面积求的是乘绩,很容易想到周长其实就是求和。也就是y坐标长度加上x坐标的长度。而tree[1].len就已经求的了目前y坐标的可加长度,只需要将它减去上一次得到的tree[1].len再取 阅读全文
posted @ 2011-11-13 14:57 Accept 阅读(1131) 评论(0) 推荐(1) 编辑
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1255这题...如果会求面积并的话,面积交就不是问题了。只需要将原先判断线段树中cover值为大于等于1改为大于等于2即可!什么都不会的同学,请看上一个随笔http://www.cnblogs.com/ka200812/archive/2011/11/13/2247064.htmlView Code 1 #include<iostream> 2 #include<string> 3 #include<stdlib.h> 4 using namespace std; 5 6 阅读全文
posted @ 2011-11-13 10:18 Accept 阅读(488) 评论(1) 推荐(0) 编辑
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1542嗯哼,要开始利用线段树求解矩形面积的并、交、以及周长了。这题是求面积并的有两种方法,一种思想很简单,操作方便,理解容易,但效率不高。先看一下吧给定一个矩形的左下角坐标和右上角坐标分别为:(x1,y1)、(x2,y2),对这样的一个矩形,我们构造两条线段,一条定位在x1,它在y坐标的区间是[y1,y2],并且给定一个cover域值为1;另一条线段定位在x2,区间一样是[y1,y2],给定它一个cover值为-1。根据这样的方法对每个矩形都构造两个线段,最后将所有的线段根据所定位的x从左到右进行排序。上图中 阅读全文
posted @ 2011-11-13 10:12 Accept 阅读(6465) 评论(10) 推荐(1) 编辑
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=3016挺有趣的一个以“是男人就下100层”为背景的题目,要求从最高处往下跳,跳到最下一层时候所得分数的最高值。这题不难,首先将线段从低到高排序,用这些线段对区间进行染色,每次染色之前先询问一边从线段的左右节点跳下去所能到达的线段。记为一条路径。最后从高到底根据我们所有的路径信息进行一次DP即可View Code 1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 using namespace st 阅读全文
posted @ 2011-11-12 16:59 Accept 阅读(461) 评论(0) 推荐(0) 编辑
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=2871求解区间内连续空闲区间!题目有四种操作:1、New X,查找一个有x连续空间的区间,并返回区间的首位置,要求答案尽量考前。如果找不到x的连续空间,则返回“Reject New”。这是最基础的线段树操作。和pku 3667、hdu 1540一样的过程2、Free X,释放第x个记忆片段,所谓第x个第一片段,指的是剩余的记忆片段中,相对来说第x次 “New x” 的结果。将其区间跟新即可,关于这道题,记录第x个记忆片段是需要技巧的,直接用数组模拟无疑是找死。纠结了许久以后,还是看了别人的结题报告,人家都是用 阅读全文
posted @ 2011-11-12 15:29 Accept 阅读(319) 评论(0) 推荐(1) 编辑
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1540又是一道跟新查找最大了连续空余区间的题目,由于每次都是炸一个点和修复一个点,所以max_val域都省下了~由于题目只要求数目,无涉及节点的先后,所以查找的话随便怎么查吧,只要你别遗漏就好了还有一个要注意的就是一个隧道是可以重复炸毁重复修复的~~View Code 1 #include<iostream> 2 #include<string> 3 #include<stack> 4 #include<algorithm> 5 using namespace 阅读全文
posted @ 2011-11-11 16:46 Accept 阅读(284) 评论(0) 推荐(0) 编辑
摘要:http://poj.org/problem?id=3667哈哈,经典中的经典题啊。利用线段树求最大连续空闲区间,并返回空闲区间的起点坐标。View Code 1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 using namespace std; 5 6 struct node 7 { 8 int l; 9 int r; 10 int l_val; //从左节点数起的最大连续空闲区间 11 int r_val; //从右节点起的最大连续空闲区间 12 ... 阅读全文
posted @ 2011-11-10 21:21 Accept 阅读(283) 评论(0) 推荐(0) 编辑
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=2795这题咋一看和线段树没啥关系似的。其实不然,非线段树不能解也!将黑板报上每一行看做一个节点线段,黑板的宽度为其容量,这样,H行黑板就对应了H个叶子节点。H的范围为10^9,看起来很大不是吗?我们再看通知的数目n,n的数目小于等于200000,也就是说,就算每一行都放一个通知,最多也只需要200000行,可见H<=10^9,这个纯属吓人的嘛为每个线段添加一个max_left域,表示该区间的最大剩余容量,采用先序遍历树的方式,在max_left>=(通知长度) 的情况下一直向下查找,知道找到根节点 阅读全文
posted @ 2011-11-10 19:57 Accept 阅读(219) 评论(0) 推荐(0) 编辑
摘要:http://poj.org/problem?id=2528又是一道区间染色问题,经典问题,自然有经典解法:为线段树添加一个cover域,当cover的值为-1的时候,则说明该区间是有多种颜色组成的。当cover为一个非-1的值时,说明该区间为cover一种颜色组成。更新的时候只需要将单色的区间信息向下传递即可这题唯一要做的,或许就是离散化吧。离散化就是利用数组的下标与其值一一对应的映射关系的一种hash。View Code 1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 usi 阅读全文
posted @ 2011-11-10 15:08 Accept 阅读(252) 评论(0) 推荐(0) 编辑
摘要:http://poj.org/problem?id=3468典型的一道基于lazy传递的线段树题目,这题和一般题目不同的地方在于,它的每次操作不是简单的覆盖线段,而是累加。记得第一次写的时候纠结了好久。好的,既然是累加,那么如何传递lazy呢?答案是传递累加值!为线段树加一个add域,表示该线段需要加几。如果某区间的add不为0,那么就将该区间的add传递给其子区间,并且跟新子区间的sum_val值。解这题最关键的就是要能够分清楚啥东西要传递,传递下去将有什么影响,其他的都好说!整体来说还是蛮轻松的View Code 1 #include<iostream> 2 #include& 阅读全文
posted @ 2011-11-09 21:28 Accept 阅读(236) 评论(0) 推荐(0) 编辑
摘要:http://poj.org/problem?id=2777又是一个区间染色问题,和一般的区间染色问题有点点不同,在于这题的线段范围比较大,如果采用cover域表示法的话会超时。所谓cover域表示法,即当cover值为-1时,表示该线段的颜色为混合色,要求的具体答案必须向下查找,直到找到cover不为-1的子区间。但是cover表示法也不错,因为我们有时候会别无选择。下面会为大家进行比较。先看这题的题解!这题虽然线段范围很大,但是我们注意到所用到的颜色最多只有30中,如果采用二进制压缩法的话,一个int 型数据即可以表示出所有的颜色(例如:1001表示了两种颜色,第一种和第四种) 。为线段树 阅读全文
posted @ 2011-11-09 21:08 Accept 阅读(316) 评论(0) 推荐(0) 编辑
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1394这道题属于利用线段树求解一个序列的逆序数的应用。由于题目要求有5000个数,普通方法求解逆序数必然导致超时( 时间为n*(n-1)/2 )。那么,利用线段树又如何求解呢?这里思维有些巧,假设有序列5 3 4 1 2。我们首先在线段[5,5]的位置上插入一个1,表示[5,5]这一线段有一个数,这个数就是5。接下来我们要插入3,在插入3之前,我们先查找一下[4,n]这一区间,看其中有多少个1,有多少个1,就表示4~n之内有多少个数在之前已经出现过了。这个值表示3的逆序数同理,一直插完最后一个数,我们便可以得 阅读全文
posted @ 2011-11-09 20:35 Accept 阅读(234) 评论(0) 推荐(0) 编辑
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1698这是一个区间染色的问题,对于区间染色问题,通常的方法是在线段树中定义一个cover域,当cover的值为-1的时候,则表示这个线段的覆盖不是有一个颜色染成的,其中包含了多种颜色,而当cover为一个非-1的值时,例如cover==1时表示该线段是有第一种颜色染成的。 对于这题,由于是成段成段的在跟新线段树,我们自然不能简单的递归到根节点再进行处理,这样毫无疑问是要超时的,所以我们只能成段的跟新。那么,如何做到成段的跟新呢?这里需要运用一种叫着lazy的思想,lazy顾名思义便是懒惰的意思。该思想大概的意 阅读全文
posted @ 2011-11-09 11:21 Accept 阅读(265) 评论(0) 推荐(0) 编辑
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1754这是一道运用线段树求解简单RMQ的题目,和敌兵布阵一样,这题的跟新操作也是对点进行的,即跟新时跟新到根节点即可,无需任何技巧。注意这题也是一点为基础单位(一个点代表一个学生),所以依然是建成点树。每次跟新后自下而上的进行最大值DP,为查询节约时间!View Code 1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 struct node 6 { 7 int l; 8 int r; 9 int.. 阅读全文
posted @ 2011-11-09 10:54 Accept 阅读(197) 评论(0) 推荐(0) 编辑
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1166这是一道线段树的基础入门题,题目中的所有跟新操作都是对点进行的,也即无需任何lazy标记传递信息。由于是对点进行的操作,我们在建树的时候应该将数建成点树,即 build(2*i,l,mid); build(2*i+1,mid+1,r); 后面将会有需要段树的题目,待续。这题唯一的技巧应该就是查找了,我们在对某点进行跟新之后,可以采用之下而上的DP方式,跟新每一段中的人数信息,这样就可以为查找节约很多时间View Code 1 #include<iostream> 2 #include< 阅读全文
posted @ 2011-11-09 10:41 Accept 阅读(373) 评论(0) 推荐(0) 编辑

点击右上角即可分享
微信分享提示