ACM_数据结构
文章平均质量分 66
亚N程
这个作者很懒,什么都没留下…
展开
-
UVa:548 Tree
这个题跪了好多次居然都是因为读错题了。它要求在某条路径最小的情况下的叶结点的值。如果存在多条最小路径,则取最小的叶结点。后序的最后一个结点是根节点。在中序序列中找到该结点的位置,右边是右子树,左边是该结点的左子树。注意要先递归右子树。直接用后序和中序推出一个树的遍历过程,然后求就行了。用不着建树。 #include#include#include#include原创 2013-12-18 17:18:32 · 644 阅读 · 0 评论 -
FZJ:1894 志愿者选拔(单调队列)
单调队列。维护一个从变动的起点到当前为区间的最大值。这里的离队操作只需要判断需要离队的人是否在单调队列中即可。原创 2014-03-18 10:19:34 · 640 阅读 · 0 评论 -
POJ:3468 A Simple Problem with Integers(线段树模版题)
线段树区间加减,区间求和。模版题。原创 2014-03-16 19:30:39 · 541 阅读 · 0 评论 -
HDU:4252 A Famous City(单调栈)
题意:给一些从正面看得到的楼的高度,问最少可能有多少楼。思路:单调栈。用一个栈维护一个单调递增序列。如果栈空或栈顶小于当前元素可将当前元素压栈,如果小于栈顶元素则将栈顶元素弹出并将答案加一,相同则无视。注意存在0的情况,即如果楼的高度是0不需要将该数字压栈。#include #include #include #include #include #include #includ原创 2015-04-18 14:24:11 · 589 阅读 · 0 评论 -
UVa:11987 Almost Union-Find(并查集)
题意:要求你实现一个并查集,有以下3个功能:1,合并两个集合;2,将某个元素移动到另一个集合中;3,求某元素所在集合的元素个数与它们的和。思路:对于普通并查集,只具备第1个功能。但是仔细研究一下功能3,发现它只查询整个集合的元素个数与和,这个是比较好实现的,只需要维护根结点的元素个数与和就行,无须维护每个父亲结点,因为功能2只能移动一个结点。问题还是在功能2上,要移动一个结点p,首先要删除它,这样会破坏并查集原来的结构,需要寻找它所有的孩子结点以改变它们的父亲,这样做比较麻烦。实际上该结点存在的意义就是连原创 2014-03-22 11:19:05 · 731 阅读 · 0 评论 -
UVa:1329 Corporative Network(带权并查集)
题意:有两种操作。1,将u设为v的父亲结点,距离为abs(u-v)%1000;2,求u到根节点的距离。思路:带权并查集。设dist[u]表示u到根节点的距离,每次压缩路径时,需要每次加上其父亲结点的dist。另外在合并时计算为dist[v]=abs(u-v)%1000+dist[u]。#include #include #include using namespace std;co原创 2014-03-11 11:57:06 · 573 阅读 · 0 评论 -
ZOJ:3634 Bounty hunter(二分+树状数组)
题意:大概就是说有一些票,编号代表只能坐从左往右第i个空座。每个人按序买了票,问最后他们都做哪个座位。思路:比较经典的模型,类似于约瑟夫环。首先将树状数组所有数字置1,每次二分前缀和得到第k个位置,该票被买走意味着将该位置数字置0。如此可以。#include #include #include #include #include #include #include using原创 2015-03-31 22:04:19 · 1180 阅读 · 0 评论 -
ZOJ:3633 Alice's present(离线处理)
题意:给一串数字,每次区间查询,输出从右往左第一个重复的数字,如果没有重复数字则输出"OK"。思路:据说此题暴力也能过,但应该不是正解。我的思路是用离线处理,先把所有查询读入,并保存为区间,根据区间右端点存进相应的vector数组中(区间右端点作为数组索引)。这样从右往左遍历所有的数字,并用一个queue(队列)来保存所有经过的查询区间。这样,一旦经过某个结点就将以该位置为右端点的查询区间存入原创 2015-03-31 21:52:28 · 479 阅读 · 0 评论 -
ZOJ:3641 Information Sharing(并查集)
题意:不说了。。思路:很明显的并查集。数据量比较小,集合可以用set维护。唯一一个值得注意的地方是可能会爆内存,因此每次合并以后原来的set要清空。#include #include #include #include #include #include #include #include using namespace std;typedef long long LL;原创 2015-03-31 22:07:55 · 458 阅读 · 0 评论 -
CodeForces 501D – Misha and Permutations Summation(康托/逆康托展开+树状数组+二分)
题意:给两个排列,分别算出是第几小的排列,这两个数字求和以后再模n!得到一个数,输出这个数对应的排列。思路:很明显的康托/逆康托展开。难点在于如何快速求解康托/逆康托以及模n!上。在康托展开中,遍历每一位是在所难免的,时间复杂度是O(n),在统计比a[i]小的数字个数的时候显然不能遍历了,可以用树状数组加速,时间复杂度是O(lgn)。这里并不得到的数字加起来,因为可能达到n!,太大了,而是原创 2015-04-22 12:41:37 · 756 阅读 · 0 评论 -
HDU:4251 The Famous ICPC Team Again(划分树)
题意:给一组数字,多次查询求中位数。思路:划分树。#include #include #include #include #include #include #include using namespace std;const int maxn=100005;struct DivideTree{ int sorted[maxn],dat[20][maxn];原创 2015-04-18 14:18:22 · 524 阅读 · 0 评论 -
UVa:1449 Dominating Patterns(AC自动机)
AC自动机模版题。找到每个串然后标记该串出现次数加一。注意模版串可能有重复,最后要全部输出。一开始因为数组开小了结果超时了。字典树开的大小应该为字符串个数n*字符串长度l原创 2014-03-11 19:42:52 · 568 阅读 · 0 评论 -
POJ:2823 Sliding Window(单调队列)
单调队列。分别用两个双端队列维护最小值和最大值。C++能过,G++超时。一开始用STL,C++也超时了,自己手写了一个过掉了。。原创 2014-03-18 09:50:31 · 561 阅读 · 0 评论 -
HDU:3333 Turing Tree (树状数组+离线处理+哈希+贪心)
题意:给一个数组,每次查询输出区间内不重复数字的和。思路:用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理。在线很难下手,考虑离线处理。将所有查询区间从右端点由小到大排序,遍历数组中的每个数字,每次将该数字上次出现位置的值在树状数组中改为0,再记录当前位置,在树状数组中修改为当前的数值。这样可以保证在接下来的查询中该数字只出现了一次。这是贪心的思想,只保留最可能被以后区原创 2015-05-06 22:28:41 · 733 阅读 · 0 评论 -
POJ:2352 Stars(树状数组)
第一次写树状数组的题,居然1Y。好难得。首先将x坐标离散化,这样使每个x都对应一个序号。然后按顺序遍历所有点,对于每个点x的序号对应一个偶数的树状数组结点,求它之前的和就是该点的level,然后该位置加1。如此循环直到结束。 #include #include #include #include #include #define MAXN 32005using namesp原创 2013-11-07 13:50:18 · 736 阅读 · 0 评论 -
UVa:1401 Remember the Word(字典树)
字典树,第一次写。还需要递推。dp【i】=sum{dp【i+len(x)】}x是str【i……L】的前缀长度。朴素的想法是枚举所有x,然后判断是否是str【i……L】的前缀,这是时间复杂度大约是30000*4000*比较的时间,会超时。利用tire减少了不必要的比较,使得可以快速找到所有的x,即每次找到的都是str【i……L】的前缀,这样至多是30000*100。关于字典树。用数组原创 2014-02-07 23:50:58 · 616 阅读 · 0 评论 -
UVa:11019 Matrix Matcher(AC自动机)
AC自动机。很容易想到一个思路将模式矩阵的每一行插入Tire,然后将匹配矩阵的每一行用AC自动机漫游,统计该行中出现过的模式矩阵行,最后判断出现过的每行是否能够组成整个模式矩阵即可。这个也很好判断。但是有个问题如果模式矩阵中的串有重复,比如说匹配阵是aaaaaaaaa模式矩阵aaaa那么很有可能得不到正确结果。所以我把AC自动机中的val数组改成了二维,原创 2014-03-12 09:52:04 · 676 阅读 · 0 评论 -
HDU:4893 Wow! Such Sequence!(线段树单点更新+区间求和)
题意:执行相应的4种操作。思路:单点更新时求最近fib,维护fib的和及元素的和。注意初始化的时候要对每个0求fib。#include#include#include#include#include#include#include#include#define LL long long#define MAXN 100001<<2using namespace std;原创 2015-04-21 10:11:08 · 546 阅读 · 0 评论 -
UPC:2224 Boring Counting(二分+划分树)
题意:给一串数字,每次查询区间内大于等于A小于等于B的数字个数。思路:二分+划分树。划分树可以求区间内第k小的数字,配合二分可以求到某个数字在区间内是第几小数字。#include #include #include #include #include using namespace std;const int maxn=50005;typedef long long LL;原创 2015-04-07 21:52:29 · 568 阅读 · 0 评论 -
UVa:12299 RMQ with Shifts
线段树单点修改+区间最值。其中shift的操作,只需要挨个改值就行了。#include #include #include #include #include #include #include #include #include #include #define ll long long#define INF 2139062143#define inf -213原创 2014-03-13 22:27:11 · 579 阅读 · 0 评论 -
POJ:3321 Apple Tree
可以用树状数组实现,每次C就是改值,每次Q就是查询。但是由于题目是给的树结构,而树状数组求和是线性区间,所以需要将题目中的树节点编号,并对每个结点划分它的子树区间以便求和。用dfs后序遍历整棵树标记序号,然后取子树中最小结点为左端点,自身编号是右端点。之后用树状数组就可以了。用vector会超时,自己写了个数组的邻接表居然AC了。#include #include #include原创 2014-03-14 23:13:10 · 563 阅读 · 0 评论 -
HDU:1166 敌兵布阵
之前用树状数组过掉了,这次用线段树重写了一遍,和求区间最值的那代码基本一样。。 #include #include #include #include #include #include #include #include #include #include #define MAXN 200005#define MOD 1000000007#原创 2014-01-25 23:11:26 · 716 阅读 · 0 评论 -
UVa:1513 Movie collection
树状数组。开始按照n,n-1,n-2,,,3,2,1插入到树状数组并记录每个数字的位置,每次取出一个数,就输出该数位置到末尾的和,然后将该位置设为0,把该数字放到末尾并记录位置。注意数组要开100000*2。树状数组求和的时候上限是n+m。#include #include #include #include #include #include #include #inclu原创 2014-03-14 19:47:40 · 540 阅读 · 0 评论 -
【完全版】线段树
FROM:http://www.notonlysuccess.com/index.php/segment-tree-complete/在代码前先介绍一些我的线段树风格:maxn是题目给的最大区间,而节点数要开4倍,确切的来说节点数要开大于maxn的最小2x的两倍 lson和rson分辨表示结点的左儿子和右儿子,由于每次传参数的时候都固定是这几个变量,所以可以用预转载 2013-08-19 17:37:32 · 655 阅读 · 0 评论 -
POJ:2886 Who Gets the Most Candies?
线段树模拟约瑟夫环+反素数。 #include #include #include #include #include #include #include #include #include #include #define ll long long#define INF 2139062143#define inf -2139062144#define MOD原创 2014-03-13 19:08:49 · 588 阅读 · 0 评论 -
UVa:11732 strcmp() Anyone?
折腾了两个多小时终于把这个题给过了。一开始想到思路直接写了个多叉的tire,结果超时了。感觉是不能再小的算法了,后来发现只memset就要很长时间,于是改成每次开辟新节点的时候再memset,还加了读入输出外挂,结果还是超时。后来上网题解上说要用左儿子右兄弟表示法来做,然后写了一个,1.7sAC了。多叉的写法,由于它直接利用下标表示对应的字符,所以对空间浪费比较严重,但是要找到某个结点的孩原创 2014-02-08 17:54:43 · 604 阅读 · 0 评论 -
UVa:11235 Frequent values
RMQ问题。用稀疏表解决的,思路照搬了白书上的。。#include #include #include #include #include #include #include #include #include #include #define MAXN 100005#define MOD 1000000007#define INF 100000原创 2014-01-24 13:02:05 · 750 阅读 · 0 评论 -
UVa:11488 Hyper Prefix Sets
Tire。思路很蠢,每个串的最后一个结点记录该串出现次数。然后在树上dfs求相同结点数*串个数的最大值。第一次用scanf超时,后来改成gets,优化了一下读入,1.8s水过。。。#include #include #include #include #include #include #define ll long long#define INF 2000原创 2014-02-08 13:15:27 · 587 阅读 · 0 评论 -
UVa:11988 Broken Keyboard (a.k.a. Beiju Text)
题很水,但是用string居然超时了。。 ans.splice(ans.begin(),temp);将temp这个链表合并在ans这个链表前头,并把temp清空。 #include #include #include #include #include #include #include #include #include #include原创 2014-01-27 21:55:12 · 598 阅读 · 0 评论 -
UVa:11991 Easy Problem from Rujia Liu?
这个题很容易想到的思路就是开一个大小为n的vector数组,每个数组下标表示数值大小,然后存每个数字的下标。这样构造是O(n),查询是O(1),但有一个缺点就是只能适用于数值比较小的情况。如果数值比较大,数组就开不下了。LRJ的思路是用map > 实现的。这样构造是O(nlogn),查询是O(logn),但是可以接受数值比较大的情况,而且初始化很好写。总之这里开的数组一定是要变长的,比如说原创 2014-01-20 13:05:47 · 618 阅读 · 0 评论 -
HDU:1394 Minimum Inversion Number
用线段树求原始序列的逆序数,然后再递推求其它时候的逆序数,比较得最小值。线段树求逆序数的原理跟树状数组一样,都是利用区间求和。我这里为了方便自己写的线段树,把下标调整成了从1开始到n把当前第一个元素移动到末尾位置时,总逆序数的变化是:加上大于该数的个数,减去小于该数的个数。 #include #include #include #include #include原创 2014-01-26 23:50:22 · 559 阅读 · 0 评论 -
HDU:1754 I Hate It
开始刷线段树的题。上一道是单值加减,区间求和,我用树状数组过掉了。这道题是单值更新,区间求最值,只能用线段树了。用了watashi翻译的那本书上的模版,把半闭半开的区间改成了全闭区间。另外数组开的大小问题还是不太懂。。 #include #include #include #include #include #include #include #includ原创 2014-01-25 22:39:31 · 800 阅读 · 0 评论 -
UVa:11995 I Can Guess the Data Structure!
水题,模拟即可。注意无错的返回,需要判断是否为空。 #include #include #include #include #include #include #include #include #define MAXN 10000#define MOD 1000000007#define INF 2139062143#define ll l原创 2014-01-20 12:37:26 · 659 阅读 · 0 评论 -
UVa:11136 Hoax or what
优先队列。使用一个最大堆和最小堆即可。但是注意最大堆里删除掉的了,可能在最小堆里出现。所以需要保证每次弹出的在另一个堆里没有删掉。所以加两个数组判断这个地方。答案要用longlong。#include #include #include #include #include #include #include #include #include #includ原创 2014-03-10 17:41:39 · 542 阅读 · 0 评论 -
HDU:2795 Billboard
再次领教了线段树的威力。维护一个最大值,优先选择左边的,更新操作写在了查询里面。 #include #include #include #include #include #include #define ll long long#define INF 2139062143#define MAXN 105using namespace std;con原创 2014-01-27 17:54:09 · 624 阅读 · 0 评论 -
UVa:12086 Potentiometers
区间求和,单点改值。用线段树实现。封装成了一个类。#include #include #include #include #include #include #include #include #include #include #define ll long long#define INF 2139062143#define inf -2139062144#def原创 2014-03-13 12:31:54 · 594 阅读 · 0 评论 -
HDU:1698 Just a Hook
线段树区间更新,区间求和。模版题。#include #include #include #include #include #include #include #include #include #include #define ll long long#define INF 2139062143#define inf -2139062144#define MOD原创 2014-03-15 21:33:17 · 604 阅读 · 0 评论 -
POJ:2828 Buy Tickets(线段树)
思路真的很奇妙。从后往前,pos的意义是此时该人前面的空位。这样用线段树寻找第k个元素即可。原创 2014-03-14 14:47:53 · 592 阅读 · 0 评论