随笔分类 -  数据结构

摘要:大白书上的题目,比较巧妙的是其分析,为了求某个i点做裁判的时候的情况数,只要知道左边有多少比它小的记为ansc,右边有多少比它小的记为ansd,则总种数,必定为ansc*(右边总数-ansd)+ansd*(左边总数-ansc)。为了速度求出ansc和ansd,用到树状数组,这倒不是很难得地方,每次读到a[i],更新a[i]值+1即可。反过来求一次即可求出来 ansd注意最后数据可能超过32位整数,因此用long long树状数组的使用还有些不熟练。。。要继续加强#include #include #include using namespace std;int x[100005];long l 阅读全文
posted @ 2014-03-11 23:46 KRisen 阅读(264) 评论(0) 推荐(0)
摘要:第一次做树状数组,这个东西还是蛮神奇的,通过一个简单的C数组就可以表示出整个序列的值,并且可以用logN的复杂度进行改值与求和。这道题目我根本不知道怎么和树状数组扯上的关系,刚开始我想直接按图来遍历来做,后来用树状数组做完都跑了600+MS,那样估计是TLE了。做法就是用DFS把整个图重建一遍,代号小的点在叶子,代号大的点为根。记录每个根的起始点号为 idl,根点号为 idh,则求某个根的苹果和就直接调用树状数组的sum即可。不过前提是要建好树,我一开始不明白为什么要建一颗标准树,即就是按1 2 3 4。。。。,每个点有一个苹果的递增的标准树,因为整个图并不是按这个标准来建得,2号点C值为1号 阅读全文
posted @ 2014-03-08 21:26 KRisen 阅读(267) 评论(0) 推荐(0)
摘要:ZJU 三月月赛题,当时见这个题目没辙,没学过splay,敲了个链表TLE了,所以回来好好学了下Splay,这道题目是伸展树的第二题,对于伸展树的各项操作有了更多的理解,这题不同于上一题的用指针表示整个树,采用纯数组表示,null节点即为0节点,这样就带来一个问题,就是有时候会有事没事就指向0节点,结果把0节点也算在结果里面,弄得我要几个地方都判断下。#include #include #include #include #define N 310000using namespace std;int tot,root,n,m;int ch[N][2],val[N],gcdst[N][2],si 阅读全文
posted @ 2014-03-07 23:26 KRisen 阅读(356) 评论(0) 推荐(0)
摘要:上次ZOJ月赛碰到一个题目要求对序列中的某个区间求gcd,并且还要随时对某位数字进行修改 插入 删除,当时马上联想到线段树,但是线段树不支持增删,明显还是不可以的,然后就敲了个链表想暴力一下,结果TLE。那天回来后搜了下题解,发现大家都在说平衡树 Splay,就好好学了下,这玩意还是挺难学的,我看了好久。最后还是从网上找了三篇论文打印了下,趁着TCG讲数据库的时候(这课真的好催眠)好好看了下,才搞清楚基本的Splay操作这是第一道Splay题目,基本上是照着模板敲出来的,没办法,第一次学,好多地方不熟练,不过整个过程我已经形成了一个条理了,这倒是一大收获由于自己的粗心,好几个细节错了,调试了好 阅读全文
posted @ 2014-03-06 20:32 KRisen 阅读(331) 评论(0) 推荐(0)
摘要:这个题目一看就是用并查集,有N个国家代表,在M行给出两两之间的关系,敌人或者朋友,(当然如果该关系跟已知关系冲突,则输出-1)关系的几个约束条件时这样的在朋友方面,朋友的朋友就是自己的朋友,这个就是并查集。在敌人方面,x和其所有朋友的敌人都是敌人。x和其所有敌人的敌人都是朋友。主要是这个敌人的状态不太好表示,不是一个并查集能做到的,我一开始犯糊涂,直接用个图把x的敌人存贮起来,但是因为每次交新的朋友或者敌人,就要搜索全图,而且要把自己的敌人圈更新到整个朋友圈,这样不仅难以实现,复杂度也是相当高后来就发现一个神级方法,简单易用,即,每个国家都有自己的对立面(实际上不存在),作用是这样的,x的对立 阅读全文
posted @ 2014-01-20 16:41 KRisen 阅读(401) 评论(0) 推荐(0)
摘要:终于AC了,这道题目去年寒假卡得我要死,最后一气之下就不做了。。。想想居然一年之久了,我本来都快忘了这道题了,最近发现白书的奥秘,觉得刘汝佳的题目真的相当练思维以及对代码的操作,决定又刷起题目来,这时候才想起这道题。用栈进行模拟堆砖块,用个rec[]数组记录其现在所在的栈号,比较麻烦的是pile 操作,为了把a以及a以上的所有砖块都以原秩序放置于b砖块顶端,我用了个临时的栈进行存贮,然后再一个一个放到b栈上面。。这样就不会破坏秩序。。但是感觉这样做挺耗时的,原以为通不过,结果还是通过了。。。22ms,也不算太高吧。。不知道还有没有更好的pile方法这个题目去年我都没想清楚题意,题目里面有个关键 阅读全文
posted @ 2013-12-05 21:55 KRisen 阅读(658) 评论(0) 推荐(0)
摘要:刘汝佳的题目感觉都是比较难以处理的,就像这道题目,一看数据简直觉得头大。。。加上这个英文我也看的想死最后看别人博客的题意讲解才知道原来是要移牌。然后如果熟练的使用stack和手写链表的话,这个题目是不成问题的#include #include #include #include #define N 100using namespace std;struct node{ char ch[3];};stack arr[N];int next[N],pre[N];int t,cnt;void deletegap(){ for (int i=0;i!=t;i=next[i]) { ... 阅读全文
posted @ 2013-12-05 20:44 KRisen 阅读(334) 评论(0) 推荐(0)
摘要:本来是个很简单的题目,难住我的主要是这么几点1.它所有的点都是坐标,不是实际的砖块,1,3指的是1-2 2-3的砖块。。。后来就是用1 代表1-2 ,2代表2-3.。。。。,这样的话,每次读入的数据,都把r--就行,然后在实际的砖块数就是 x[r+1]-x[l]。2.我动手太快,没想清楚它是叠层型,即每次读入砖块坐标,都是往原有砖块的基础上++,这样的话,懒惰标记,就也一定是每次++,这里我WA了好久,一开始没想清楚,没按叠层来更新懒惰标记。。3.有个地方超级难以想到,就是在最后query木板能承载多少砖块的时候,用个flag标记好已经完全清空的node,因为询问有多次,下次再遇到这个node 阅读全文
posted @ 2013-11-12 11:58 KRisen 阅读(431) 评论(1) 推荐(0)
摘要:给这个题目跪了两天了,想吐简直发现自己离散化没学好包括前一个离散化的题目,实际上是错了,我看了sha崽的博客后才知道,POJ那题简直数据弱爆了,本来随便一组就能让我WA掉的,原因在于离散化的时候,缩小数据规模的同时,没有考虑到误差,比如 1 4 6 8,离散化之后是1 2 3 4,我如果覆盖了1 2和3 4,表面上好像全部覆盖了,实际数据并没有覆盖。。所以我只能说那道题目我其实错了,并没有真正做出离散化出来。。。现在用这道题来弥补。color the ball,ball的编号可以从1 到2^31,不可能开这么大线段树,但是其实测试数据只有N=2000*2组,所以必然是离散化,初始的时候,所有球 阅读全文
posted @ 2013-11-09 21:03 KRisen 阅读(447) 评论(0) 推荐(0)
摘要:给一块最大为10^8单位宽的墙面,贴poster,每个poster都会给出数据 a,b,表示该poster将从第a单位占据到b单位,新贴的poster会覆盖旧的,最多有10^4张poster,求最后贴完,会看到几张poster (哪怕只露出一个单位,也算该poster可见);我一看这么大数据,又看了下时间限制只有1s,不科学啊,如果真的按10^8建树不可能过时间啊,而且根据它的空间限制,大概只能建10^7这么大的数组。后来搜博客发现大家的标题都写着离散化,原来用离散化做这个题目,但是我不会离散化,我想找一篇纯讲离散化的博文来好好研究下,。。。没找到,所以原谅我,这个题目是仔仔细细的分析了别人的 阅读全文
posted @ 2013-11-06 16:57 KRisen 阅读(513) 评论(0) 推荐(0)
摘要:题意:给一棵树,每个节点都有一个权值,权值只能拿一次,只让走K步,问最多能拿到多少权值这个题目一开始没料到原来可以往回走,分析了样例才知道。之后我用DFS搜索,超时后来一直想树形DP的状态转移,一直没想出来。后来还是看别人博客上的状态转移方程。dp[0][rt][j+2]=max(本身,dp[0][rt][w]+dp[0][nx][j-w])//w为枚举的需要多少步,由于要从nx子节点返回,故需要比j多两步dp[1][rt][j+2]=max(本身,dp[1][rt][w]+dp[0][nx][j-w])//走向子树后回来再一去不回,因为从子树回来需要多走两步dp[1][rt][j+1]=ma 阅读全文
posted @ 2013-11-03 14:15 KRisen 阅读(165) 评论(0) 推荐(0)
摘要:题意:就是相当于动规里面的求最大连续子串,不同的是,这里需要读入一个区间x,y,输出的区间 a,b 且x#include #include #define Lson x=s[tree[x=s[r]-s[tree[x=v2){ tree[x].vx=tree[xs[tree[x].vy]-s[tree[x].vx-1]){ tree[x].vx=tree[xmid){ return query(st,e,Rson); } if (e=s[b.vy]-s[b.vx-1]){ c.vx=a.vx; c.vy=a.vy;... 阅读全文
posted @ 2013-11-02 10:09 KRisen 阅读(575) 评论(0) 推荐(0)
摘要:最近做DP题目,发现无论是LCS,还是有些题目涉及将动态规划的路径打印出来,而且有时候还要按格式输出,这个时候,记忆化搜索显得尤其重要,确实,记忆化搜索使用优化版本的动态规划,用起来思路清晰,非常方便这个题目就是一个n*n的图里,从起点出发,只能横向或者纵向走最多k步,而且每次下个点都要比当前点的值要高,这样最终走完获得的总点权值最大是多少明显的是一BFS 或者DFS,当然,我们稍微优化下,用记忆化搜索,就会成为很优化版本的DFS。所以从代码看,这样的记忆化搜索,其实是从起点出发,但是最终要搜到最后一点,然后层层返回,此时,每个得到了返回值的点都已经是最优点了,所以下次再搜到这个点直接返回,这 阅读全文
posted @ 2013-10-15 12:04 KRisen 阅读(398) 评论(0) 推荐(0)
摘要:1012: City TourTime Limit:1 SecMemory Limit:128 MBSubmit:63Solved:11[Submit][Status][Web Board]DescriptionAlice想要从城市A出发到城市B,由于Alice最近比较穷(不像集训队陈兴老师是个rich second),所以只能选择做火车从A到B。不过Alice很讨厌坐火车,火车上人比较多,比较拥挤,所以Alice有很严格的要求:火车的相邻两站间的最大距离尽可能的短,这样Alice就可以在停站的时候下车休息一下。当然Alice希望整个旅途比较短。Input有多组测试数据。每组测试数据的第一行有 阅读全文
posted @ 2013-08-22 16:53 KRisen 阅读(452) 评论(0) 推荐(0)
摘要:第一次涉及HASH查找的知识对于字符串的查找有很多前人开发出来的HASH函数,比较常用的好像是ELF 和 BKDR。这道题没想到突破点是在于其nc值,告诉你组成字符串的字母种类。还有用26进制,不管怎么说,只要避免产生冲突,怎么哈希都行。用的是BKDRHash法。#include #include #include #define maxn 20000000#define mm 1000000using namespace std;int hash[maxn]={0};char str[mm];int news[mm]={0};int ans;int n,nc;int BKDRHash(cha 阅读全文
posted @ 2013-08-21 15:07 KRisen 阅读(270) 评论(0) 推荐(0)
摘要:DescriptionThe cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as their vacation residence. This immense hotel h 阅读全文
posted @ 2013-08-20 10:41 KRisen 阅读(245) 评论(1) 推荐(1)
摘要:题目大意:在h*w 高乘宽这样大小的 board上要贴广告,每个广告的高均为1,wi值就是数据另给,每组数组给了一个board和多个广告,要你求出,每个广告应该贴在board的哪一行,如果实在贴不上,就输出-1;这个题目也难以想到居然是用线段树来做我们需要考虑的是,线段树究竟表示的是什么数据。在这个题目里,由于每个广告的高都为1,是不是好像感觉每一行都是一个叶子节点一样。没错,就是这样。。。化抽象为具体一点,那就是把这个board给竖起来,这样最底部的孩子存贮了当前行的空闲宽度,每个父节点都是左右孩子的max。其实思路这样理一下,感觉其实很简单,是把。还要注意的一点是,虽然题目说h 和 w高达 阅读全文
posted @ 2013-08-15 10:05 KRisen 阅读(152) 评论(0) 推荐(0)
摘要:题目大意:依次描述了一个N个人的队伍,每个人所站的序号以及他的价值,依次描述每个人的过程中,存在序号相同的人,表示该人插入到了前一个序号相同的人的前面。最后输出整个队伍的值排列情况。这个题目确实难以想到居然可以用线段树做,之前还脑残去敲什么链表,结果发现链表这玩意儿真不是一般的垃圾,好多地方根本就无法对时间进行优化。当然了,就算告诉了你用线段树做,可能还是会很头疼,这里涉及插队操作。。而且线段树具体是存放什么东西的呢线段树就是为了模拟当前队伍的空位数,比如一个4人队伍,Root肯定是值为4 然后左右孩子都为 2 2 ,最底下4个孩子均为1,表示该位置还可以插入几个人插队操作是比较蛋疼的,为了避 阅读全文
posted @ 2013-08-15 09:51 KRisen 阅读(194) 评论(0) 推荐(0)
摘要:终于线段树还是有所领悟,发现对一个算法真的是,一开始云里雾里,后来这些天狂搞图论,数据结构,把KMP,Manacher,最短路,最小生成树 都狂弄了一下之后,发现再来弄线段树就容易多了,至少建树,更新什么的,我脑海里已经可以自己构图了。。所以,一个心得是,算法可以让脑子变的灵活聪明,前几天看的云里雾里的东西,过几天就会有领悟了。好了,进入正题。挑了一道还算可以的线段树题目,上午A了一道,完全是纯线段树水题,这题涉及懒惰标记,感觉高端了好多。。就算用了懒惰标记,仍然跑了将近3000MS,话说最近做图论题目发现,G++总是比C++要多几百MS(数据量本身比较大的时候)。。。而且尤其碰到几个坑题,用 阅读全文
posted @ 2013-08-13 17:27 KRisen 阅读(223) 评论(0) 推荐(0)
摘要:受教了,感谢玉斌大神的博客。这道题最难的地方就是操作2,将一个集合中的一个点单独移到另一个集合,因为并查集的性质,如果该点本身作为root节点的话,怎么保证其他点不受影响。玉斌大神的思路很厉害,受教受教,即,由于题目最终输出集合的元素个数与权值总和,故添加一个delete操作,将该点(设为P)所在集合的rank和sum值减小,将p的father引向一个从没定义过的点,(可以设置为(总数++)点),这样,虽然看似P还留在原集合,但仅仅作为一个空骨架,并不对集合的rank和sum产生影响。具体实现,需要借助一个辅助数组 id[], id[]初始和father[]相同,但一旦需要删除操作,即将id[ 阅读全文
posted @ 2013-08-10 15:33 KRisen 阅读(366) 评论(0) 推荐(0)