树状数组&线段树&RMQ

来源:互联网 发布:智能小车pid算法 编辑:程序博客网 时间:2024/05/17 06:50

附上一个不错的介绍:http://hawstein.com/posts/binary-indexed-trees.html

Range Minimum Query and Lowest Common Ancestor --- http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor

树状数组要特别注意的就是在idex=0的情况了,不然要死循环=。=

线段树的化要注意初始化空间大小为4*M = 2^0+2^1+...+2^(log(M)+1),M为数据规模的最大值

RMQ等会补充

线段树版本

#include <iostream>#include <stdio.h>#include <algorithm>#include <vector>#include <stack>#include <string>#include <cmath>#include <map>#include <set>using namespace std;typedef pair<int, int> pii;typedef long long LL;const int MAXV = 32000+5;const int MAXN = 15000+5;struct p {int l,r,w;}T[MAXV*4]; //2^0+2^1+...+2^(log(M)+1) = 4Mint res[MAXN];//节点n的区间设置为【s,t】void buildTree(int s, int t, int n){T[n].l = s;T[n].r = t;T[n].w = 0;if(s==t) return;int mid = (T[n].l + T[n].r)/2;buildTree(s, mid, 2*n);buildTree(mid+1, t, 2*n+1);}//在n节点查询区间【s,t】的值int find(int s, int t, int n){if(T[n].l == s && T[n].r == t)return T[n].w;int mid = (T[n].l + T[n].r)/2;//下一个查询区间以mid为分割int sum = 0;if(s>mid)sum += find(s, t, 2*n+1);else if(t<=mid)sum += find(s, t, 2*n);else {sum += find(s, mid, 2*n);sum += find(mid+1, t, 2*n+1);}return sum;}//自顶向下更新void update(int n, int x){T[n].w ++;if(T[n].l==T[n].r && T[n].r==x)//到叶子节点结束递归return;int mid = (T[n].l + T[n].r)/2;if(x<=mid) update(2*n, x);else update(2*n+1, x);}int main(){freopen("input.txt", "r", stdin);int n; buildTree(1, MAXV, 1);scanf("%d", &n);for(int i=0; i<n; ++i){int x, y;scanf("%d %d", &x, &y);x++;y++;res[find(1, x, 1)]++;update(1, x);}for(int i=0; i<n; ++i)printf("%d\n", res[i]);}

树状数组版本

#include <iostream>#include <stdio.h>#include <algorithm>#include <vector>#include <stack>#include <string>#include <cmath>#include <map>#include <set>using namespace std;typedef pair<int, int> pii;typedef long long LL;const int MAXV = 32000+5;const int MAXN = 15000+5;int a[MAXN], res[MAXN];int c[MAXV];int lowbit(int x){return x&(-x);}int getsum(int n){int sum = 0;while(n>0){sum+=c[n];n -= lowbit(n);}return sum;}void update(int n, int v){while(n<MAXV){c[n] += v;n += lowbit(n);}}int main(){//freopen("input.txt", "r", stdin);int n; scanf("%d", &n);{for(int i=0; i<n; ++i){int x, y;scanf("%d %d", &x, &y);x++;res[getsum(x)]++;update(x, 1);}for(int i=0; i<n; ++i)printf("%d\n", res[i]);}}


0 0
原创粉丝点击