数据结构
文章平均质量分 90
ACdreamers
这个作者很懒,什么都没留下…
展开
-
调度场算法与逆波兰表达式
本文的主要内容是如何求一个给定的表达式的值,具体思路就是先将普通算术的中缀表达式转化为后缀表达式,这一步用到的算法叫做调度场算法。然后对后缀表达式,也就是逆波兰表达式求值。题目:http://acm.hdu.edu.cn/showproblem.php?pid=3596代码:原创 2015-06-09 21:37:27 · 6470 阅读 · 3 评论 -
线段树求区间和(单点更新)
题目1:敌兵布阵 线段树的主要操作:(1)建立线段树(Build) (2)更新区间值 (Update) (3)查询区间(Query)写法一:#include #define maxn 55555#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int sum[maxn<<2原创 2012-09-26 16:45:03 · 1454 阅读 · 0 评论 -
POJ2155(二维树状数组)
题目:Matrix 本题是赤裸裸的二维树状数组,意思很明白。。。。#include #include const int N = 1005;int C[N][N];int Lowbit(int x){ return x & (-x);}void Update(int x,int y,int value){ int i,原创 2013-03-20 23:39:32 · 1064 阅读 · 0 评论 -
POJ2019(二维RMQ问题 ST)
题目:Cornfields 只是注意本题数据定义小一点,不然会超内存。#include #include #include using namespace std;const int N = 255;int n, b, k;short val[N][N];short dpmax[N][N][10][10];short dpmin[N]原创 2013-03-19 18:02:38 · 1459 阅读 · 0 评论 -
离散化+树状数组求逆序数
题目:POJ2299 离散化是一种常用的技巧,有时数据范围太大,可以用来放缩到我们能处理的范围 因为其中需排序的数的范围0---999 999 999;显然数组不肯能这么大;而N的最大范围是500 000;故给出的数一定可以与1.。。。N建立一个一一映射;这里用一个结构体struct Node { int v,order; }p[510000];和一个数组原创 2013-01-19 14:52:12 · 7020 阅读 · 2 评论 -
HDU2888(二维RMQ)
题目:Check Corners 本题碉堡了,内存限制好紧,再大一点都不行,还只能用int,开始用short WA了好多次。。。。。 题意:给一个矩阵,然后给Q个询问,每个询问有四个数,分别代表询问的子矩阵的左上角和右下角,然后找出子矩阵的最大值输出,然后再把这个值与子矩阵的四个角的值比较,如果有至少一个等于这个最大值就输出“yes”,否则输出“no”。#include原创 2013-03-20 19:48:30 · 1507 阅读 · 0 评论 -
HDU3183(RMQ问题,ST算法)
题目:A Magic Lamp 题意:对于一个序列A[1...N],一共N个数,除去M个数使剩下的数组成的整数最小。也就是说在A[1...N]中顺次选取N-M个数,使值最小。本题很有技巧性,一开始我总是想不明白,后来在纸上画了一下,大概明白了是怎么回事。它主要是基于以下事实:对于序列A[1...N],选取N-M个数,使组成的值最小,而且顺序不能交换,既然原创 2013-03-19 16:29:27 · 4099 阅读 · 0 评论 -
RMQ问题(区间求最值)
RMQ的树状数组实现:#include #define N 100005int idx[N];int num[N];int n,m,l,r,i,j;int min(int a,int b){ return a<b? a:b;}int lowbit(int x){ return x&(-x);}void init()原创 2013-02-23 17:34:52 · 1152 阅读 · 0 评论 -
ST算法解决RMQ问题
关于ST算法,实际上它本身并不难,它的思想是动态规划。主要用来求RMQ问题,时间复杂度为O(NlgN+M) 关于RMQ问题描述:输入N个数和M次询问,每次询问一个区间[L,R],求第L个数到R个数之间的最大值,或者是求最小值。 它的原理阐述如下:对于一个数组A[0...N-1],我们用f[i][j]表示A[i]到A[i+2^j-1],这个范围内的最大值。由于此区间的元素原创 2013-03-19 15:38:43 · 1364 阅读 · 0 评论 -
POJ2352 stars(树状数组)
题目:Stars #include #include const int N = 32005;int C[N];int level[N];int Lowbit(int x){ return x & (-x);}void Update(int x){ int i; for(i=x;i<=N;i+=Lowbi原创 2013-03-21 01:05:46 · 969 阅读 · 0 评论 -
一维树状数组
树状数组是对一个数组改变某个元素和求和比较实用的数据结构。两中操作都是O(logn)。 在解题过程中,我们有时需要维护一个数组的前缀和S[i]=A[1]+A[2]+...+A[i]。 但是不难发现,如果我们修改了任意一个A[i],S[i]、S[i+1]...S[n]都会发生变化。 可以说,每次修改A[i]后,调整前缀和S[]在最坏情况下会需要O(n)原创 2012-09-27 20:59:22 · 1317 阅读 · 0 评论 -
POJ1151(线段树+扫描线求矩形面积并)
题目:http://poj.org/problem?id=1151 #include #include #include #include using namespace std;const int N = 10005;struct node{ int l,r; int cov; double len;};str原创 2013-09-20 20:08:03 · 2297 阅读 · 0 评论 -
线段树求逆序数(单点更新)
题目:HDU1394 Minimum Inversion Number 若abcde...的逆序数为k,那么bcde...a的逆序数是多少?我们假设abcde...中小于a的个数为t , 那么大于a的个数就是n-t-1,当把a移动最右位时,原来比a大的现在都成了a的逆序对,即逆序数增加n-t-1,但是原来比a小的构成逆序对的数,现在都变成了顺序,因此逆序对减少t ,所以新序列的逆序数为原创 2013-02-09 11:53:28 · 3464 阅读 · 0 评论 -
二维树状数组
题目:Counting Black #include #include #define MAXN 200int flag[MAXN][MAXN];int c[MAXN][MAXN];int lowbit(int i){ return i&(-i);}void update(int x,int y,int color){ if(原创 2012-10-08 14:28:27 · 1335 阅读 · 0 评论 -
HDU4302(map的用法)
题目:Holedox Eating #include #include #include #include #include using namespace std;const int oo=1000000;int main(){ mapmymap; int t,l,n,co,a,b,ca=0; map::iterato原创 2013-05-30 16:28:11 · 1615 阅读 · 0 评论 -
区间第K大(划分树)
题目:区间中第K大的数 注意一个很明显的结论:求区间[p,q]的第K大就等于求区间[p,q]的第q-p+1-k小。#include #include #define N 100005int sorted[N];int Tree[20][N];int toLeft[20][N];void Build(int k,int l,int r){ i原创 2013-03-29 15:46:27 · 1532 阅读 · 0 评论 -
二叉树的恢复
数据结构实验:#include #include #include typedef char datatype;typedef struct node{ datatype data; struct node *lchild,*rchild;}bitree;int search(datatype x,datatype *tree){原创 2013-03-03 14:14:56 · 1731 阅读 · 0 评论 -
线段树空间容纳且最上边的数(单点更新)
题目:HDU2795 Billboard#include #define maxn 222222#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int w,h,n;int MAX[maxn<<2];int max(int a,int b){ return a>b? a:b;}void原创 2013-02-09 14:40:36 · 977 阅读 · 0 评论 -
线段树求区间最大值RMQ(单点更新)
题目:HDU1754#include #define maxn 222222#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int MAX[maxn<<2];int max(int a,int b){ return a>b? a:b;}void PushUP(int rt){原创 2013-02-09 00:19:48 · 3011 阅读 · 0 评论 -
线段树HDU1698(成段更新)
题目:Just a Hook 延迟标记(或者说懒惰标记),简单来说就是每次更新的时候不要更新到底,用延迟标记使得更新延迟到下次需要更新or询问到的时候。#include #define N 111111#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int n;int col[N<<2];int sum原创 2013-02-10 19:08:31 · 1338 阅读 · 0 评论 -
约瑟夫环问题
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2211题意:N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人重新从1开始报数。问最后剩下的人的编号。例如:N = 3,K = 2。2号先出列,然后是1号,最后剩下的是3号。分析:实际上对于约瑟夫环问题,最常见的有3种解法。第一种就是原创 2013-12-30 19:33:53 · 3624 阅读 · 0 评论 -
归并排序求逆序对
我们知道,求逆序对最典型的方法就是树状数组,但是还有一种方法就是Merge_sort(),即归并排序。实际上归并排序的交换次数就是这个数组的逆序对个数,为什么呢?我们可以这样考虑:归并排序是将数列a[l,h]分成两半a[l,mid]和a[mid+1,h]分别进行归并排序,然后再将这两半合并起来。在合并的过程中(设l当a[i]>a[j]时,在前半部分中比a原创 2013-11-20 21:11:38 · 41440 阅读 · 2 评论 -
优先队列的应用
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1163 分析:本题采用优先队列是一个比较好的选择,每次替换之前最小的。 代码:#include #include #include #include #include using namespace std;const int N =原创 2014-08-30 19:16:27 · 3498 阅读 · 0 评论 -
原地归并排序
今天要讨论的问题是Inplace Merge Sort,即原地归并排序。相比传统的归并排序,它的空间复杂度仅为。 在讨论这个问题之前,我们先来看Perfect Shuffle问题,描述如下 问题:输入,如何用的时间和的空间,把原序列变为。原创 2014-04-21 18:51:47 · 8068 阅读 · 5 评论 -
堆操作与堆排序
首先,我们来认识堆: 堆的建立:将给定的序列按层次遍历建立完全二叉树,然后从最后一个非终端结点开始自下向上逐步调整为堆。 这里就有两个重要的操作,shift_up(int t)和shift_down(int t),这样我们就建立了堆。对于堆排序,就相当于每次取出堆顶的元素值,这样是从大到小排序的,因为建立的是大顶堆。 现在来详细说一点:比如对于序列:5 8 9 7 6原创 2013-11-11 19:35:53 · 4761 阅读 · 0 评论 -
单调队列
单调队列是这样一个队列,队列中的所有元素是单调递增或者单调递减。它可以在队首或队尾删除元素,但是只能在队尾插入元素。由于每个元素入队和出队一次,所以维护队列的均摊时间复杂度为O(1)。题目:http://poj.org/problem?id=2823题意:给一个数组a[],求它连续m个元素中的最小值和最大值。比如输入:8 31 3 -1 -3 5 3 6 7原创 2014-03-10 13:17:41 · 2126 阅读 · 2 评论 -
两个栈实现一个队列
今天我要讲的是如何用两个栈实现一个队列。我们知道对于栈,它是先进后出,而对于队列,它是先进先出。所以用两个栈实现一个队列最直观的思路就是:设这两个栈分别为s1,s2,始终把s1作为存储空间,把s2作为临时空间。那么 (1)入队时 把元素压入s1 (2)出队时 先把s1中除最底下所有元素都倒入s2,然后弹出s1的唯一元素,再把s2的原创 2014-03-07 13:51:41 · 5737 阅读 · 0 评论 -
位图
位图法就是用一个位来存放某个数据的存在状态。比如:用一个20位长的内存空间可以表示一个所有元素都小于20的简单的非负整数集合。对于集合{1,2,3,5,8,13}可用如下方式表示 0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0这样,我们就可以用20位来表示上面集合所有元素的存在状态。当然利用位图我们可以节省很多空间原创 2014-01-19 19:20:25 · 1860 阅读 · 0 评论 -
POJ2886线段树 Joseph游戏(单点更新)
题目:Who Gets the Most Candies? 题意:1.n个人进行Joseph游戏,游戏共p轮(p为 思路:用相对坐标来处理,例如这一轮出局的是p,下一个要+m,则p出局时p+1就变成了p(因为是相对坐标),则下一个人应该是p+m-1,再注意循环和m的正负的处理,不要忘了取模。2.求解原始序号时维护一棵线段树,类似上一题插队的方法建树,每个节点为该区间段的人数原创 2013-02-09 16:56:49 · 3409 阅读 · 0 评论 -
POJ2828线段树 插队(单点更新)
题目:Buy Tickets#include #define N 200010#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int tree[N<<2];int pos[N],val[N],ans[N];int id;void Build(int l,int r,int rt){ tree[原创 2013-02-09 16:22:12 · 1013 阅读 · 0 评论 -
HDU1823(二维线段树)
题目:Luck and Love 题意:当操作符为‘I’时,表示有一个MM报名,后面接着一个整数,H表示身高,两个浮点数,A表示活泼度,L表示缘分值。(100当操作符为‘Q’时,后面接着四个浮点数,H1,H2表示身高区间,A1,A2表示活泼度区间,输出符合身高和活泼度要求的MM中的缘分最高值。 (100其实对于二维线段树,可以这样理解:母树保存x轴上面的信息;子树保存当原创 2013-05-15 16:00:31 · 1695 阅读 · 0 评论 -
HDU4267(2012长春网络赛)
题目:A Simple Problem with Integers #include #include #include using namespace std;const int N = 50100;struct node{ int l; int r; int w; int add[55] ;}p[N原创 2013-03-27 16:46:53 · 1178 阅读 · 0 评论 -
线段树POJ3468(成段更新,区间求和)
题目:A Simple Problem with Integers#include #define N 111111#define LL long long#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1LL add[N<<2];LL sum[N<<2];void PushUP(int rt){原创 2013-02-10 19:50:54 · 9115 阅读 · 2 评论 -
HDU2665(函数式线段树-区间第K大)
题目:K-th Number 如果求区间第K小,就转换一下就行了,假设你要求区间[u,v]的第k小,那就是第v-u+1-k大#include#include#define N 100010int T[N];int num[N];int san[N];int ls[N*20];int rs[N*20];int sum[N*20];int tot原创 2013-03-10 19:15:23 · 5746 阅读 · 2 评论 -
POJ2528 线段树+离散化+hash(成段更新)
题目:Mayor's posters 题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报思路:这题数据范围很大,直接搞超时+超内存,需要离散化:离散化简单的来说就是只取我们需要的值来用,比如说区间[1000,2000],[1990,2012] 我们用不到[-∞,999][1001,1989][1991,1999][2001,2011][2013,+∞]这些值,所以我只原创 2013-02-10 21:09:52 · 1573 阅读 · 0 评论 -
ZKW线段树
题目:敌兵布阵 题意:给一个数组,然后有一系列操作:(1)把某一个值加上一个数,(2)把某一个值减去一个数,(3)求一段区间的和。#include #include #include using namespace std;const int N=100005;int M;int T[4*N];void PushUP(int rt){原创 2013-08-31 10:41:00 · 6462 阅读 · 0 评论 -
HDU3255(线段树+扫描线)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3255 题意:在一块地上种蔬菜,对于同一块地蔬菜价值高的一定是最后存活,求最后的蔬菜总值,也就是不同的矩形覆盖,有的矩形肯定在最上面。 #include #include #include #include using namespace std;const in原创 2013-09-20 21:19:28 · 2143 阅读 · 0 评论 -
链栈基本操作
#include #include typedef struct node{ int data; struct node *next;}NODE;NODE *crea_linkstack(){ NODE *top,*p; int a,n; top=NULL; printf("\n输入链栈的元素数目:"); scanf("%d",&n); if原创 2012-08-22 09:25:43 · 1133 阅读 · 0 评论 -
二叉树的操作
二叉树的操作:#include #include #include #define MaxSize 100#define MaxWidth 40typedef char ElemType;typedef struct tnode{ ElemType data; struct tnode *lchild,*rchild;}BTNode;char r原创 2012-11-10 12:12:12 · 1045 阅读 · 0 评论 -
BST(Binary Search Tree 二叉查找树模版)
/******************************************数据结构:BST(Binary Search Tree),二叉查找树;性质:若结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;该结点的左、右子树也分别为二叉查找树;遍历:对于一个已知的二叉查找树,原创 2013-05-09 19:47:26 · 1140 阅读 · 0 评论