抽象数据结构

1、树状数组

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <iostream>
 6 #include <algorithm>
 7 using namespace std;
 8 #define INF ~0U>>1
 9
10 const int MAX=300;
11 int n,num[MAX],c[MAX],X,Y;
12
13 int lowbit(int x){ return x&(-x);}
14
15 int SUM(int l,int r){//区间查询
16     int sum=0;
17
18     for(int i=r;i;i-=lowbit(i)) sum+=c[i];
19     for(int i=l;i;i-=lowbit(i)) sum-=c[i];
20
21     return sum;
22 }
23
24 void change(int x,int m){ for(int i=x;i<=n;i+=lowbit(i)) c[i]+=m;}//单点修改
25
26 int main(){
27     memset(c,0,sizeof(c));
28
29     cin >> n;
30     for(int i=1;i<=n;i++){
31         cin >> num[i];
32         for(int j=i-lowbit(i)+1;j<=i;j++) c[i]+=num[j];
33     }
34
35     cout << "1 X Y:sum[Y]-sum[X](X<Y)" << endl << "2 X Y:num[X]=Y" << endl << "0:end" << endl;
36
37     int i;
38     do{
39         cin >> i >> X >> Y;
40         if(!i) break;
41         if(i==1) cout << SUM(X,Y) << endl;
42         if(i==2) change(X,Y),cout << "FINISH!" << endl;
43     }while(i);
44
45     return 0;
46 }

2、线段树

http://blog.csdn.net/metalseed/article/details/8039326

①单点修改替换,查询区间最值区间求和

 1 #include<iostream>
 2 #include<algorithm>
 3 #define lson l,m,rt<<1
 4 #define rson m+1,r,rt<<1|1
 5 #define maxn 10000
 6 int n,rt,Max[maxn<<2],Min[maxn<<2],Sum[maxn<<2],a[maxn<<2];
 7 using namespace std;
 8 void pushup(int rt){
 9     Max[rt] = max(Max[rt<<1],Max[rt<<1|1]);
10     Min[rt] = min(Min[rt<<1],Min[rt<<1|1]);
11     Sum[rt] = Sum[rt<<1]+Sum[rt<<1|1];
12 }
13 void buildtree(int l,int r,int rt){
14     if(l == r){
15         Max[rt] = Min[rt] = Sum[rt] = a[l];
16         return;
17     }
18     int m = (l+r)>>1;
19     buildtree(lson);
20     buildtree(rson);
21     pushup(rt);
22 }
23 void setval(int p,int v,int l,int r,int rt){
24     if(l == r){
25         Max[rt] = Min[rt] = Sum[rt] = v;
26         return;
27     }
28     int m = (l+r)>>1;
29     if(p <= m) update(p,v,lson);
30     else update(p,v,rson);
31     pushup(rt);
32 }
33 void addval(int p,int v,int l,int r,int rt){
34     if(l == r){
35         Max[rt] += v;
36         Min[rt] += v;
37         Sum[rt] += v;
38         return;
39     }
40     int m = (l+r)>>1;
41     if(p <= m) update(p,v,lson);
42     else update(p,v,rson);
43     pushup(rt);
44 }
45
46 int query_max(int L,int R,int l,int r,int rt){
47     if(L <= l && r <= R) return Max[rt];
48     int m = (l+r)>>1;
49     int ret = 0;
50     if(L <= m) ret = max(ret,query(L,R,lson));
51     if(R > m) ret = max(ret,query(L,R,rson));
52     return ret;
53 }
54 int query_min(int L,int R,int l,int r,int rt){
55     if(L <= l && r <= R) return Min[rt];
56     int m = (l+r)>>1;
57     int ret = 0;
58     if(L <= m) ret = min(ret,query(L,R,lson));
59     if(R > m) ret = min(ret,query(L,R,rson));
60     return ret;
61 }
62 int query_sum(int L,int R,int l,int r,int rt){
63     if(L <= l && r <= R) return Sum[rt];
64     int m = (l+r)>>1;
65     int ret = 0;
66     if(L <= m) ret += query(L,R,lson);
67     if(R > m) ret += query(L,R,rson);
68     return ret;
69 }
70
71 int main(){
72     cin>>n;
73     buildtree(1,n,1);
74     return 0;
75 }

②区间修改,查询区间最值区间求和

  1 #include<iostream>
  2
  3 #include<algorithm>
  4
  5 using namespace std;
  6
  7 const long long int INF = 100000000;
  8
  9 const int maxn = 2000000 + 10;
 10
 11 long long int sumv[maxn], minv[maxn], maxv[maxn], addv[maxn];//sumv[]:如果只执行结点o及其子孙结点中的add操作,结点o对应区间中所有数之和
 12
 13 long long int my_y1, my_y2, v, n, m;//修改/查询范围均为[my_y1,my_y2];
 14
 15 void mantain(int o, int l, int r){
 16
 17 int lc = o * 2, rc = o * 2 + 1;
 18
 19 sumv[o] = minv[o] = maxv[o] = 0;
 20
 21 if (r > l){//考虑左右子树
 22
 23 sumv[o] = sumv[lc] + sumv[rc];
 24
 25 minv[o] = min(minv[lc], minv[rc]);
 26
 27 maxv[o] = max(maxv[lc], maxv[rc]);
 28
 29 }
 30
 31 minv[o] += addv[o]; maxv[o] += addv[o]; sumv[o] += addv[o] * (r - l + 1);
 32
 33 //考虑add操作
 34
 35 }
 36
 37 //在执行add操作时,哪些结点需啊哟调用上述maintain函数呢?很简单,递归访问到的结点全部要调用,并且是在递归返回后调用。
 38
 39 void update(int o, int l, int r){
 40
 41 int lc = o * 2, rc = o * 2 + 1;
 42
 43 if (my_y1 <= l&&my_y2 >= r){//递归边界
 44
 45 addv[o] += v;
 46
 47 }
 48
 49 else{
 50
 51 int m = l + (r - l) / 2;
 52
 53 if (my_y1 <= m) update(lc, l, m);
 54
 55 if (my_y2 > m) update(rc, m + 1, r);
 56
 57 }
 58
 59 mantain(o, l, r);
 60
 61 }
 62
 63
 64
 65 long long int _min, _max, _sum;//全局变量,目前位置的最小值、最大值和累加和
 66
 67 void query(int o, int l, int r, int add){
 68
 69 if (my_y1 <= l&&my_y2 >= r){//递归边界:用边界区间的附加信息更新答案
 70
 71 _sum += sumv[o] + add*(r - l + 1);
 72
 73 _min = min(_min, minv[o] + add);
 74
 75 _max = max(_max, maxv[o] + add);
 76
 77 }
 78
 79 else{//递归统计,累加参数add
 80
 81 int m = l + (r - l) / 2;
 82
 83 if (my_y1 <= m) query(o * 2, l, m, add + addv[o]);
 84
 85 if (my_y2 > m) query(o * 2 + 1, m + 1, r, add + addv[o]);
 86
 87
 88
 89 }
 90
 91 }
 92
 93 int main(){
 94
 95 int i, j;
 96
 97 cin >> n;
 98
 99 for (i = 1; i <= n; i++)
100
101 {
102
103 cin >> v;
104
105 my_y1 = my_y2 = i;
106
107 update(1, 1, n);
108
109 }
110
111 cin >> m;
112
113 for (i = 1; i <= m; i++){
114
115 int q;
116
117 cin >> q;
118
119 if (q == 1){
120
121 cin >> my_y1 >> my_y2 >> v;
122
123 update(1, 1, n);
124
125
126
127 }
128
129 else{
130
131 int y;
132
133 cin >> my_y1>>my_y2;
134
135 _sum = 0; _min = INF; _max = -INF;
136
137 query(1, 1, n, 0);
138
139 cout << _sum << endl;
140
141 }
142
143 }
144
145 system("pause");
146
147 }

③区间替换,区间求和

 1 #include<iostream>
 2 #include<algorithm>
 3 #define lson l,m,rt<<1
 4 #define rson m+1,r,rt<<1|1
 5 #define maxn 10000
 6 int n,rt,sum[maxn<<2],col[maxn<<2];//col是延迟标记
 7 using namespace std;
 8 void pushup(int rt){
 9     sum[rt] = sum[rt<<1] + sum[rt<<1|1];//或min,max
10 }
11 void pushdown(int rt,int m){
12     if(col[rt]){
13         col[rt<<1] = col[rt<<1|1] = col[rt];
14         sum[rt<<1] = (m-(m>>1)) * col[rt];
15         sum[rt<<1|1] = (m>>1) * col[rt];
16         col[rt] = 0;
17     }
18 }
19 void buildtree(int l,int r,int rt){
20     col[rt] = 0;
21     sum[rt] = 1;
22     if(l == r) return;
23     int m = (l+r)>>1;
24     buildtree(lson);
25     buildtree(rson);
26     pushup(rt);
27 }
28 void update(int L,int R,int c,int l,int r,int rt){
29     if(L <= l && r <= R){
30         col[rt] = c;
31         sum[rt] = c*(r-l+1);
32         return;
33     }
34     pushdown(rt,r-l+1);
35     int m = (l+r)>>1;
36     if(L <= m) update(L,R,c,lson);
37     if(R>m) update(L,R,c,rson);
38     pushup(rt);
39 }
40 int query(int L,int R,int l,int r,int rt){
41     if(L <= l && r <= R) return sum[rt];
42     int m = (l+r)>>1;
43     int ret = 0;
44     if(L <= m) ret += query(L,R,lson);
45     if(R > m) ret += query(L,R,rson);
46     return ret;
47 }
48 int main(){
49     cin>>n;//5
50     buildtree(1,n,1);//12345
51     update(1,5,2,1,n,1);
52     update(5,9,3,1,n,1);
53     cout<<query(1,n,1,n,1);
54     return 0;
55 }

3、Spare Table

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <cstdlib>
 6 #include <cstring>
 7 using namespace std;
 8 #define MAX 50010
 9
10 int top,n,x,y;
11 int f[MAX*2][30],f2[MAX*2][30];
12 int seq[MAX*2];
13
14 int rmq(){
15     int m=(int)(log((double)top-1)/log(2.0));
16
17     for(int i=1;i<top;++i) f[i][0]=seq[i],f2[i][0]=seq[i];
18
19     for(int j=1,k=1<<(j-1);j<=m;++j,k=1<<(j-1))
20         for(int i=1;i+(1<<(j-1))<top;++i){
21             f[i][j]=min(f[i][j-1],f[i+k][j-1]);
22             f2[i][j]=max(f2[i][j-1],f2[i+k][j-1]);
23         }
24
25     return 0;
26 }
27
28 int query(int l,int r){
29     int k=(int)(log(r-l+1.0)/log(2.0));
30
31     if(l>r)swap(l,r);
32
33     return max(f2[l][k],f2[r-(1<<k)+1][k])-min(f[l][k],f[r-(1<<k)+1][k]);
34 }
35
36 int main(){
37     cin >> top >> n;
38     top++;
39
40     for(int i=1;i<top;i++) cin >> seq[i];
41
42     rmq();
43
44     while(n--){
45         cin >> x >> y;
46         cout << query(x,y) << endl;
47     }
48
49     return 0;
50 }

时间: 2024-10-14 14:31:01

抽象数据结构的相关文章

线性表的比较和抽象数据结构(栈&amp;队列)的实现方式

链表的两种底层结构 1.ArrayList实现单链表(其实就是一个顺序数组) ArrayList其实就是一组长度可变的数组,当实例化了一个ArrayList,该数据也被实例化了,当向集合中添加对象时,数组的大小也随着改变,这样它所带来的有优点是快速的随机访问(数组可以利用下标直接访问),即使访问每个元素所带来的性能问题也是很小的,但缺点就是想其中添加或删除对象速度慢,当你创建的数组是不确定其容量,所以当我们改变这个数组时就必须在内存中做很多的处理,如你想要数组中任意两个元素中间添加对象,那么在内

分布式缓存技术redis学习系列(二)——详细讲解redis数据结构(内存模型)以及常用命令

Redis数据类型 与Memcached仅支持简单的key-value结构的数据记录不同,Redis支持的数据类型要丰富得多,常用的数据类型主要有五种:String.List.Hash.Set和Sorted Set. Redis数据类型内存结构分析 Redis内部使用一个redisObject对象来表示所有的key和value.redisObject主要的信息包括数据类型(type).编码方式(encoding).数据指针(ptr).虚拟内存(vm)等.type代表一个value对象具体是何种数

《C算法.第1卷,基础、数据结构、排序和搜索(第三版)》pdf

下载地址:网盘下载 内容简介  · · · · · · <C算法>介绍了当今最重要的算法,共分3卷,<C算法(第1卷):基础.数据结构.排序和摸索>是第1卷.第1卷分4部分.共16章.第一部分"基础知识"(第1-2章)介绍了基本算法分析原理.第二部分"数据结构"(第3-5章)讲解算法分析中必须掌握的数据结构知识.主要包括基本数据结构.抽象数据结构.递归和树.第三部分"排序"(第6-11章)按章节顺序分别讨论了基本排序方法(

Redis 基础数据结构与对象

Redis用到的底层数据结构有:简单动态字符串.双端链表.字典.压缩列表.整数集合.跳跃表等,Redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统,这个系统包括字符串对象.列表对象.哈希对象.集合对象和有序结合对象共5种类型的对象. 1 简单动态字符串 redis自定义了简单动态字符串数据结构(sds),并将其作为默认字符串表示. struct sdshdr { unsigned int len; unsigned int free; char buf[

redisbook笔记——redis内部数据结构

在Redis的内部,数据结构类型值由高效的数据结构和算法进行支持,并且在Redis自身的构建当中,也大量用到了这些数据结构. 这一部分将对Redis内存所使用的数据结构和算法进行介绍. 动态字符串 Sds(Simple Dynamic String,简单动态字符串) Sds在Redis中的主要作用有以下两个: 1. 实现字符串对象(StringObject): 2. 在Redis程序内部用作char* 类型的替代品: 对比C 字符串,sds有以下特性: –可以高效地执行长度计算(strlen):

Redis 一、数据结构与对象--五大数据类型的底层结构实现

redis上手比较简单,但是它的底层实现原理一直很让人着迷.具体来说的话,它是怎么做到如此高的效率的?阅读Redis设计与实现这本书,可以很好的理解Redis的五种基本类型:String,List,Hash,Set,ZSet是如何在底层实现的.还可以了解Redis的其他机制的原理.我们现在来看看Redis中的基本的数据结构吧. 简单动态字符串 Redis的简单动态字符串,通常被用来存储字符串值,几乎所有的字符串类型都是SDS的.另外,SDS还常被用作缓冲区(buffer):AOF模块中的AOF缓

Java数据结构与算法(第一章综述)

数据结构和算法能起到什么作用? 数据结构是对在计算机内存中(有时在磁盘中)的数据的一种安排.数据结果包括数组.链表.栈.二叉树.哈希表等等.算法对这些结构中的数据进行各种处理,例如,查找一条特殊的数据项或对数据进行排序. 可用于下面三类情况: 现实数据存储 程序员的工具 建模 数据结构的特性: 数据结构 优点 缺点 数组 插入快,如果知道下标,可以非常快地存取 查找慢,删除慢,大小固定 有序数组 比无序的数组查找快 删除和插入慢,大小固定 栈 提供后进先出的方式存取 存取其他项很慢 队列 提供先

数据结构(2)链表的应用

链表是一种基础数据结构,它是集合类的抽象数据结构类型中表示数据的合适类型.与数字结构不同之处在于,在链表中插入元素和删除元素都更加方便. 定义: 链表表示的一列元素,由一系列的节点(Node)构成,是一种递归数据结构.节点是一个能够包含任何类型数据的抽象实体,它所包含的指向节点的应用体现了他在链表中的作用. 构造: private class Node { public T Data; public Node Next; public Node(T data) { Data = data; }

[0x01 用Python讲解数据结构与算法] 关于数据结构和算法还有编程

忍耐和坚持虽是痛苦的事情,但却能渐渐地为你带来好处. ——奥维德 一.学习目标 · 回顾在计算机科学.编程和问题解决过程中的基本知识: · 理解“抽象”在问题解决过程中的重要作用: · 理解并实现抽象数据结构: · 复习Python编程语言 二.写在前面 自第一台电子计算机使用线路和开关传达人类的指令以来,我们编程的思考方式有了很大的改变,在很多方面,计算机技术的发展为计算机科学家提供了众多的工具和平台去实现他们的想法.高性能理器,高速网络和大内存使得计算机研究者必须掌握在这样复杂的螺旋式通道中