随笔分类 -  数据结构--线段树状数组

Minimum Inversion Number(最小翻转次数)
摘要:hdoj1394题目大意:刚开始看错了题目,以为求出逆序数就行了,就是求不出样例的值,有看原来是求出一系列的逆序数序列的最小数解决:树状数组#include <iostream>#include <cstdio>using namespace std;#define LL __int64const int N=5000;int n;int num[N+5];int c[N+5];inline int lowbit(int x){ return x&(-x);}void update(int p,int delta){ for(int i=p;i<=n;i+ 阅读全文
posted @ 2011-09-27 19:07 猿类的进化史 阅读(439) 评论(0) 推荐(0)
Frosh Week
摘要:hdoj 3743题目大意:就是逆序数解决:树状数组+离散化,以后再也不会让题目给骗了,题目上并没有说是有多组测试数据,一直wa,不知道怎么回事,以为算法出问题了呢,但是可以运行一会时间,却原来是因为有多组测试数据,以后要注意,无论是若题目没有明确说明是一组,就按照多组来。顺便有练习下树状数组的离散化过程,其实和前边的的超快速排序没什么不一样,但是这次是从另一个角度出发的,统计出这个数出现之前所有比这个数大的数的个数,就是需要交换的次数了。#include <iostream>#include <algorithm>using namespace std;const i 阅读全文
posted @ 2011-09-27 16:59 猿类的进化史 阅读(395) 评论(0) 推荐(0)
Cow Sorting
摘要:hdoj 2838题目大意:给出数,求排成正序的最少时间,每两个数交换的时间是 两个数的值的和。解决:树状数组,只需求出 在这个数加入之前比这个数大的个数,然后更新,再求出这个数加入之前比这个数大的数的总和总共的代价是:cnt*加入的数+比这个数大的数的和#include <iostream>#include <functional>#include <algorithm>using namespace std;#define LL __int64const int N=100000;LL sum[N+5]; //第i个数前比数num[i]大的数的和 LL 阅读全文
posted @ 2011-09-27 15:38 猿类的进化史 阅读(333) 评论(0) 推荐(0)
stars
摘要:hdoj 2642解决:二维树状数组简单最后的时候,必须判断下x与a,y与b的关系,若x>a或者y>b将无法处理#include <iostream>#include <algorithm>using namespace std;const int N=1001;//一个是树状数组,一个是状态标记int c[N+5][N+5];bool s[N+5][N+5];int m;inline int lowbit(int x){ return x&(-x);}inline void update(int x,int y,int inc){ for(int 阅读全文
posted @ 2011-09-25 17:00 猿类的进化史 阅读(183) 评论(0) 推荐(0)
Color the ball(给球涂色)
摘要:hdoj 1556解决:树状数组基础,插段求点 数据大小100000/*本来是不打算写这个报告,就是一个基础的插段问点,但是ac之后,又搜了一个代码,让对树状数组有了一点新的认识,就从新改了一下,仍然是可以向后更新,向前求和,只是更新的时候,多更新的要减去,求点的时候向前累计,只有更新到的点才有值*/#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int N=100005;int c[N];int n;int lowbit(int x){ retu 阅读全文
posted @ 2011-09-25 13:08 猿类的进化史 阅读(454) 评论(1) 推荐(0)
敌兵布阵
摘要:hdoj 1166题目大意:解决:树状数组简单题,不解释#include <iostream> #include <cstdio>#include <cstring>using namespace std;#define L(x) (x<<1)#define R(x) (x<<1|1)#define M(x,y) ((x+y)>>1)int n;int c[50005];int lowbit(int x){ return x&(-x);}void updata(int p,int inc){ for(int i=p 阅读全文
posted @ 2011-09-16 19:10 猿类的进化史 阅读(320) 评论(0) 推荐(0)
Ultra-QuickSort(超快速排序)
摘要:题目大意:给出一些数,用最小的交换相邻两个数,使得为正序,求最小交换次数解决:可以用归并排序,由于在士兵杀敌系列中已经用过了,所以为了练练何为树状数组中的离散化,再用树状数组做了一遍/*本题思路,首先将范围在0 ≤ a[i] ≤ 999,999,999之间的点压缩到0- 500,000之间,然后统计每个数之前所有比这个数小的*/#include <iostream> #include <cstdio>#include <algorithm>#include <cstring>using namespace std;int n;struct nod 阅读全文
posted @ 2011-08-22 13:44 猿类的进化史 阅读(828) 评论(0) 推荐(1)
Matrix(矩阵)
摘要:poj 2155题目大意:第一行给出测试用例的次数,第二行第一个 给出矩阵的size,第二个给出命令的个数C表示更新数据,将范围在x1<=x<=x2,和y1<=y<=y2区域内的数每个都加上1,Q表示询问某一个点的大小解决:二维树状数组,与poj1195 mobile phones刚好相反,是插入区域,问点#include <iostream> #include <cstdio>#include <cstring>using namespace std;const int N=1010;int c[N][N];void init(){ 阅读全文
posted @ 2011-08-22 13:34 猿类的进化史 阅读(399) 评论(0) 推荐(0)
Mobile phones(电话簿)
摘要:poj 1195题目大意:给出0时初始化,给出1时将矩阵中坐标为x,y的增加A,给出2时 查询区域为l<=x<=r, b<=r<=t范围内的总和解决:二维树状数组,只要知道一维中如何插点问段,这个便顺利写出#include <iostream>#include <cstdio>using namespace std;const int N=1200;int c[N][N];int n;void init(){ memset(c,0,sizeof(c));}int lowbit(int x){ return x&(-x);}void upd 阅读全文
posted @ 2011-08-22 13:28 猿类的进化史 阅读(268) 评论(0) 推荐(0)
Stars (星星)
摘要:poj 2352题目大意:解决:树状数组,关键是要将x轴的下标从一开始可以将x都加1#include <iostream>#include <cstdio>using namespace std;const int N=32005;int n;int c[N];int lev[N];int lowbit(int x){ return x&(-x);}void updata(int pos,int inc){ for(int i=pos;i<N;i+=lowbit(i)) c[i]+=inc;}int getsum(int pos){ int sum=0; 阅读全文
posted @ 2011-08-21 11:36 猿类的进化史 阅读(445) 评论(0) 推荐(0)
st算法介绍
摘要:实现过程及原理:首先是预处理用DP解决。设a[i]是要求区间最值的数列,f[i][j]表示从第i个数起连续2^j个数的最大值。例如数列3 2 4 5 6 8 1 2 9 7 ,f[1][0]表示从第一个数起,长度为2^0个数的最大值,其实就是第一个元素3本身。f[1][2]=5,f[1][3]=8…….从这里可以看出f[i][0]实际就是a[i]。这样dP的初始值就有了,剩下的就是状态转移方程。我们把f[i][j]平均分成两段(因为f[i][j]的值一定是个偶数0),从i到i+2^(j-1)-1为一段,i+2^(j-1)到i+2^j-1为一段。用上例说明,当i=1,j=3时就是3 2 4 5和 阅读全文
posted @ 2011-08-07 14:23 猿类的进化史 阅读(243) 评论(0) 推荐(0)
士兵杀敌(四)
摘要:题目解决方案一:线段树 1916ms 47100B C/C++可以看到用线段树解决非常的浪费空间#include <iostream>#include <cstdio>using namespace std;#define L(x) (x<<1)#define R(x) ((x<<1)+1)#define M(x,y) ((x+y)>>1)const int N=1000005;struct node{ int l,r,score;};node tree[4*N];/*此处建立的线段树为[a,b][b+1,c]类型,由于询问的是点的大 阅读全文
posted @ 2011-08-06 20:06 猿类的进化史 阅读(215) 评论(0) 推荐(0)
士兵杀敌(三)
摘要:题目描述解决方案一:用线段树解决,因为查询的是某区间的最值时间1396 空间 5304代码长度75#include <iostream>#include <algorithm>#include <cstdio>using namespace std;struct node{ int l,r,min,max;};const int N=100005;int num[N];#define L(x) (x<<1)#define R(x) ((x<<1)+1)#define M(x,y) ((x+y)>>1)node tree[4 阅读全文
posted @ 2011-08-06 16:16 猿类的进化史 阅读(279) 评论(0) 推荐(0)
士兵杀敌(二)
摘要:题目解决:(树状数组)本题是树状数组的基本应用符合两个特征,1、求区间和 2、修改的是单个元素 #include <iostream> #include <cstdio>using namespace std;const int N=1000005;int c[N];int n;//该函数功能是求出n二进制中最右边0的个数的2次幂,也等于c[n]包含的元素个数num[n-lowbit(n)+1]+...+num[n]int lowbit(int n){ return n&(-n);}//更新数组中pos的值使它加上inc,更新首先更新c[pos]一直更新该点的父 阅读全文
posted @ 2011-08-06 15:08 猿类的进化史 阅读(246) 评论(0) 推荐(0)
A Simple Problem with Integers(关于整数的问题)
摘要:poj 3468题目大意:给定Q(1 ≤ Q≤ 100,000)个数A1,A2… AQ,,以及可能多次进行的两个操作:1)对某个区间Ai … Aj的个数都加n(n可变)2) 求某个区间Ai … Aj的数的和2) 求某个区间Ai … Aj的数的和解决:线段树/*线段树的区间有两种形式,第一种是[1,2][2,3],第二种是[1,1],[2,2],在这里,由于我们查询的区间和是不能相交的,所以只能采用第二中形式,*/#include <iostream>#include <cstdio>using namespace std;typedef long long intt;s 阅读全文
posted @ 2011-08-06 10:15 猿类的进化史 阅读(371) 评论(0) 推荐(0)