随笔分类 -  树状数组 & 线段树

摘要:同POJ 2299 也是利用树状数组求逆序数的应用将x从大到小排序,若x相同,按y从大到小排序,对y建立树状数组,根据逆序数的定义,画图演算一遍就很清楚了#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAXN 1001struct Pair{ int x, y;}p[1000010];int n, m, k;int c[MAXN];int cmp(const void *a, const void *b){ if(((Pair*)a)->x == ((Pair*)b)-& 阅读全文
posted @ 2011-04-17 14:48 L.. 阅读(253) 评论(0) 推荐(0)
摘要:逆序数的定义:在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。如2431中,21,43,41,31是逆序,逆序数是4,为偶排列。 --摘自百度百科记录数列的下标,按数列的值从小到大排序,所以后面插入的值肯定比前面的大,i - getsum(c[i].pos)就可以算出在i之前还有几个比c[i]大的数,累加就是答案#include <stdio.h>#include <stdlib.h>#include <stri 阅读全文
posted @ 2011-04-17 14:29 L.. 阅读(184) 评论(0) 推荐(0)
摘要:/*按照大牛博客顺序做的题目 以前离散化好好理解了下注意离散化后struct SegTree{ int l, r; int color; int getMid(){ return (l + r) >> 1; }}tree[MAXN << 2];中l,r不是原区间的坐标了,而是排序去重后数组中对应的下标做这题问题不大 基本上1A 第一次数组开小了 囧.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#define L(x) ((x) << 1)#define 阅读全文
posted @ 2011-04-12 14:33 L.. 阅读(208) 评论(0) 推荐(0)
摘要://二维数状数组 需要注意的是下标从1开始 lowbit(0) = 0.. 超时陷阱,一定要谨记啊! 还有是c++的输入输出2600ms scanf 547ms#include <iostream>#include <stdio.h>using namespace std;const int MAXN = 1025;int tree[MAXN][MAXN];int p[MAXN];int n; //坐标范围 1 ~ 1inline int lowbit(int t){ return t & (-t);}void add(int x, int y, int val 阅读全文
posted @ 2011-04-11 23:20 L.. 阅读(193) 评论(0) 推荐(0)
摘要:/*线段树更新节点,区间最值*/#include <stdio.h> #include <stdlib.h>const int MAXN = 200001;int MAX(int x, int y){ return x > y ? x : y;}struct segTree{ int L,R; int max;};segTree tree[MAXN << 2];int st[MAXN];void bulid(int left,int right, int t){ tree[t].L = left; tree[t].R = right; if( left 阅读全文
posted @ 2011-04-10 22:45 L.. 阅读(167) 评论(0) 推荐(0)
摘要:#include <iostream>#include <algorithm>#include <stack>#define L(x) ((x) << 1)#define R(x) ((x) << 1 | 1)using namespace std;const int MAXN = 50000;struct SegTree{ int l, r; int mval, lval, rval; int cover; //1 没坏 0 坏 -1 有的坏了 有的没坏 void init(int c){ lval = rval = mval = 阅读全文
posted @ 2011-04-10 05:37 L.. 阅读(383) 评论(0) 推荐(1)
摘要:还得好好理解一下...为什么注释部分去掉 不能AC ? 知道的麻烦指导一下!#include <stdio.h>#define L(x) ((x) << 1)#define R(x) ((x) << 1 | 1)const int MAXN = 200000;struct SegTree{ int l,r; int metal; int value; bool lazy; int getMid(){ return ( l + r ) >> 1; } int getDis(){ return (r - l + 1); }}tree[MAXN < 阅读全文
posted @ 2011-04-09 01:12 L.. 阅读(188) 评论(0) 推荐(0)
摘要:给你一段数列 两个操作"Cabc" means addingcto each ofAa,Aa+1, ... ,Ab. -10000 ≤c≤ 10000. 一段区间同时增加一个值"Qab" means querying the sum ofAa,Aa+1, ... ,Ab.查询一段区间的值这题很好的体现了lazy_tag的思想,当要增加的区间覆盖当前区间,则直接打上标记返回,当下次查询这个区间儿子区间的时候,直接标记往下传。可以想象,这个标记表示的是这个区间表示的整个区间的标记,是整个子树的性质,当你不需要用到这个区间的儿子区间的时候,你可以不把操作都做到 阅读全文
posted @ 2011-04-08 16:48 L.. 阅读(323) 评论(0) 推荐(0)
摘要:/*题目已按x,y轴排序 画个图就理解了*/#include <stdio.h>#include <stdlib.h>const int MAXN = 15001;int n;int a[32001]; //树状数组 int level[MAXN];int lowbit(int t){ return t & (-t); }void add(int t){ while(t <= 32001){ a[t]++; t += lowbit(t); }}int sum(int t){ int ans = 0; while(t > 0){ ans += a[t] 阅读全文
posted @ 2011-04-07 20:43 L.. 阅读(109) 评论(0) 推荐(0)
摘要:经典的染色问题,很明显的体现了lazy——tag思想.../*用cin超时...*/#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#define L(t) ((t) << 1)#define R(t) ((t) << 1 | 1)using namespace std;const int MAXN = 1000002;bool used[33];struct SegTree{ int l, r; int color; 阅读全文
posted @ 2011-04-07 20:41 L.. 阅读(210) 评论(0) 推荐(0)
摘要:/*第一类信息ll, rr, len递推求解第二类信息state.表示整个子树的性质*/#include <stdio.h>#include <algorithm>#define L(x) ((x) << 1)#define R(x) ((x) << 1 | 1)using namespace std;const int MAXN = 50002;int N, M;struct SegTree{ int l, r; int ll, rr; //最左边,右边可用连续区间长度 int len; //最长连续可用房间长度 int state; //0 阅读全文
posted @ 2011-04-07 20:33 L.. 阅读(363) 评论(0) 推荐(1)
摘要:数状数组 模板题/*(1) Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30)(2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30);(3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数;(4)End 表示结束,这条命令在每组数据最后出现;当然线段树也可以解决,不过没树状数组方便 哈哈*/#include <iostream>#include <stdlib.h>#include <string.h>using namespace std;const int MAXN = 阅读全文
posted @ 2011-04-07 17:23 L.. 阅读(185) 评论(0) 推荐(1)