上一页 1 ··· 32 33 34 35 36 37 38 39 40 ··· 85 下一页
  2012年3月21日
摘要: HDU_1754 这个算是我的splay的处女作了,要不是为了练splay真心不想把这个可以用线段树轻松搞定的题敲得这么复杂……努力了一下午+半个晚上终于把splay的基本操作搞懂了。 其实感觉splay的旋转操作和SBT差不多,只不过多了人字旋转和一字旋转,这样要比单一从底向上旋转更能维护splay的树高。 另外对于一个问题说一点自己的看法:splay要写一个rotate_to的函数,就是将某个位置的元素旋转到goal的下方,而为什么是下方而不是恰好旋转到goal呢?因为如果是设定恰好旋转到goal的话,最后一步会把goal旋转跑,就没办法判定是否旋转到位了,所以要写成旋转到goal的下方, 阅读全文
posted @ 2012-03-21 21:52 Staginner 阅读(414) 评论(0) 推荐(0) 编辑
  2012年3月20日
摘要: POJ_2985 这个题目以cats的个数为关键字建立线段树去做,我为了练一下昨天刚学的SBT所以就用SBT写了,不过SBT的效率要低一些。#include<stdio.h>#include<string.h>#define MAXD 200010#define MAXM 400010int N, M, T, node, p[MAXD], left[MAXM], right[MAXM], key[MAXM], size[MAXM], s[MAXM];int find(int x){ return p[x] == x ? x : (p[x] = find(p[x]));} 阅读全文
posted @ 2012-03-20 15:19 Staginner 阅读(301) 评论(0) 推荐(0) 编辑
摘要: POJ_2761 本来想搜一下SBT的题练一下昨天刚学的SBT的,但这种查询静态区间内的kth number的题目还是用划分树更好写一些,所以就用划分树写了,就当是复习一下前几天学的划分树了。#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAXD 100010int N, M, rank[20][MAXD], sa[MAXD], a[MAXD], h[20][MAXD];int cmp(const void *_p, const void *_q){ int *p = (int *) 阅读全文
posted @ 2012-03-20 13:50 Staginner 阅读(292) 评论(0) 推荐(0) 编辑
摘要: POJ_3481 为了练一下昨天刚学的SBT,所以就用SBT写了,但实际上这个题目可以通过维护一个最大堆和一个最小堆就能实现所有操作。#include<stdio.h>#include<string.h>#define MAXD 1000010int T, node, key[MAXD], client[MAXD], left[MAXD], right[MAXD], size[MAXD];void left_rotate(int &T){ int k = right[T]; right[T] = left[k]; left[k] = T; size[k] = s 阅读全文
posted @ 2012-03-20 12:52 Staginner 阅读(307) 评论(0) 推荐(0) 编辑
摘要: HDU_4006 为了练一下昨天刚学的SBT,所以就用SBT写了,但实际上这个题目只需要维护一个只有k个元素的最小堆即可,每次查询就输出堆顶的元素,如果insert的元素比堆顶元素大,就把堆顶元素删掉,然后把这个insert的元素插入到堆中。#include<stdio.h>#include<string.h>#define MAXD 1000010int N, K, T, left[MAXD], right[MAXD], node, key[MAXD], size[MAXD];void left_rotate(int &T){ int k = right[T] 阅读全文
posted @ 2012-03-20 11:40 Staginner 阅读(265) 评论(0) 推荐(0) 编辑
  2012年3月19日
摘要: HYSBZ_1053 这个算是平衡树的处女作啦,争取这两天能够练到熟练地敲出平衡树O(∩_∩)O~ 这个题目比较坑人的地方就是题目中明明说“如果初始工资低于下界他将立刻离开公司”,但偏偏最后的结果是不算这部分人的。 这个题目可以用平衡树做,也可以用线段树做,用线段树的话就以工资为关键字建立线段树,但这样实际上是受工资大小的限制的,如果工资变化幅度比较大的话线段树就还要增加离散化的操作。#include<stdio.h>#include<string.h>#define MAXD 100010int T, node, left[MAXD], right[MAXD], si 阅读全文
posted @ 2012-03-19 23:50 Staginner 阅读(1027) 评论(0) 推荐(0) 编辑
  2012年3月18日
摘要: POJ_3463 题目要求去求最短路以及比最短路大1的所有路径的数量。 如果单求最短路数量的话,我们可以直接用SPFA+dp或者dij+dp去做,而这个题目不过是多了一个相当于次短路的数量的问题,因此我们可以把每个点拆成两个点,一个点记录最短路的距离及路径数量,另一个记录次短路距离及路径数量,用dij+dp去处理应该更方便一些。 每次更新时,如果比最短路小,就把次短路的相关数据先更新成之前的最短路的数据,然后再更新最短路的数据,如果比最短路大但比次短路小就只需更新次短路的数据,其他的一些情况就比较好分析了。#include<stdio.h>#include<string.h& 阅读全文
posted @ 2012-03-18 00:43 Staginner 阅读(411) 评论(0) 推荐(0) 编辑
  2012年3月17日
摘要: POJ_3013 如果按题目中的计算方法去想的话,是很难想到合适的算法的,而如果换个角度考虑问题的就海阔天空了。 题目中是以边为中心去考虑的,如果我们以点为中心去考虑,最后的结果就是各点的点权和该点到根的边权和相乘之后再求和即可,于是只要根到每个点途径的边权和最小就行了,那么自然就是最短路了。#include<stdio.h>#include<string.h>#define MAXD 50010#define MAXM 100010#define INF 1000000000000000llint N, M, D, a[MAXD], inq[MAXD], q[MAXD 阅读全文
posted @ 2012-03-17 23:39 Staginner 阅读(184) 评论(0) 推荐(0) 编辑
摘要: UVALive_5825 一个可行的思路就是扫描一遍,求出以i为左端点的且长度不超过N的区间和的最小值,如果这个最小值都大于或等于0的话,那么显然以i为左端点就是可行的。 既然是区间求和,那么一般来说用前缀和比较方便,这样实际上对于每个i我们就是去找满足j>i&&j<=i+N的最小的A[j],其中A[]表示前缀和。 我是用后缀和做的,如果用后缀和的话结论类似。#include<stdio.h>#include<string.h>#define MAXD 2000010#define INF 0x7fffffffint N, M, A[MAXD 阅读全文
posted @ 2012-03-17 09:27 Staginner 阅读(195) 评论(0) 推荐(0) 编辑
摘要: URAL_1846 思考之后一个可行的方式就是对于每次插入、删除完毕之后快速的求出剩余数的gcd。 但是直接去求是不行的,不过思考一下之后会发现gcd和求和运算有一些相似的地方,比如gcd(a,b,c,d)=gcd(gcd(a,b)+gcd(c,d))就好比sum(a,b,c,d)=sum(sum(a,b),sum(c,d)),于是就想到可不可以用线段树去查询呢?当然可以,只要线段树上其余的值初始化成0,树顶的元素就是所有值的gcd。 想到这里就还剩一个问题了,每个数怎么和线段树上的位置对应起来,因为我们要完成插入、删除操作就必须快速找到对应元素的位置,我是用哈希表处理的,网上也有离散化去.. 阅读全文
posted @ 2012-03-17 09:07 Staginner 阅读(534) 评论(0) 推荐(0) 编辑
上一页 1 ··· 32 33 34 35 36 37 38 39 40 ··· 85 下一页