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

摘要:http://acm.hdu.edu.cn/showproblem.php?pid=3308注意两个地方 向上更新 和查找的时候向上更新1.左儿子最右边的值<右儿子最左边的值lMax=(左儿子的lMax==左儿子的len)?左儿子的len+右儿子的lMax:左儿子的lMax;rMax=(右儿子的rMax==右儿子的len)?右儿子的len+左儿子的rMax:右儿子的rMax;Max=MAX(左儿子的rMax+右儿子的lMax,左儿子的Max,右儿子的Max,lMax,rMax);2.左儿子最右边的值>=右儿子最左边的值lMax=左儿子的lMax;rMax=右儿子的rMax;Max= 阅读全文
posted @ 2013-03-22 18:01 _雨 阅读(655) 评论(0) 推荐(1)
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1541题被划在线段树里 刚开始想着是求区间k值 写着写着觉得错了 看着像求逆序数 写了个树状数组 怎么都过不了 无奈。。View Code 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define N 50000 7 struct node 8 { 9 int x,y,p;10 }s[N&l 阅读全文
posted @ 2012-10-22 18:49 _雨 阅读(189) 评论(0) 推荐(0)
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=2795放在第几行 就是第几行的剩余空值x》xi 以行建树 求区间第K值View Code 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define N 200010 7 #define LL __int64 8 LL s[N<<2],h,ww; 9 void build(int 阅读全文
posted @ 2012-10-21 22:03 _雨 阅读(192) 评论(0) 推荐(0)
摘要:http://poj.org/problem?id=3225先贴代码 有空再解释View Code 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define N 140000 7 int s[N<<2],kc[N<<2],hash[N]; 8 void build(int l,int r,int w) 9 { 10 kc[w] = 0; 11 s[w] 阅读全文
posted @ 2012-10-21 22:00 _雨 阅读(201) 评论(0) 推荐(0)
摘要:http://poj.org/problem?id=3667之前网络赛水过一道区间合并的题 当时是全靠运气试对的 。昨天纠结了一晚上也没看出来哪错,改的都跟人家代码一样了还是不对,今天又重新敲了一遍,莫名的就对了,,开两个数组分别存这个区间两端点的连续区间 再开一标记数组 用来更新 向上向下都要更新View Code 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define 阅读全文
posted @ 2012-10-18 13:35 _雨 阅读(223) 评论(0) 推荐(0)
摘要:划分树+二分枚举http://acm.hdu.edu.cn/showproblem.php?pid=4417划分树http://www.cnblogs.com/pony1993/archive/2012/07/17/2594544.html直接搬来模板 打得View Code 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 #define N 100005 6 int a[N], as[N];//原数组,排序后数组 7 int 阅读全文
posted @ 2012-09-24 11:36 _雨 阅读(238) 评论(1) 推荐(0)
摘要:http://poj.org/problem?id=2828险过 3500+ms第i个人入队 只影响后面的不会影响前面的 可以倒推 全初始化为1 第i个人去第k位置 由于是倒推,第k个位置为0,表示求k-1位置的时候不能算上k位置的人 根据区间和 求出区间第K值 就是第i个人要放的位置View Code 1 #include <iostream> 2 #include<cstdio> 3 #include<string.h> 4 using namespace std; 5 #define N 200001 6 int s[N*4],d[N*2][2],po 阅读全文
posted @ 2012-09-05 13:24 _雨 阅读(252) 评论(0) 推荐(0)
摘要:RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就是说,RMQ问题是指求区间最值的问题。http://poj.org/problem?id=32641A 程序跑的好慢 3000+输完更新 父节点的最小最大值 找的时候找两次 一次最大 一次最小 相减View Code 1 #include <iostream> 2 #include<cstdio> 3 #include<string.h> 4 using nam 阅读全文
posted @ 2012-09-05 09:12 _雨 阅读(154) 评论(0) 推荐(0)
摘要:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2426这题本来是按高度从大到小找的 要向上向下都得更新啊 结果TLE了 然后又从小到大排序线段树+离散化 把对应的值开个数组存起来 最后算面积的时候 用离散前的值算 高度从小到大排好序更新 这样比较简单View Code 1 #include<stdio.h> 2 #include<iostream> 3 #include<string.h> 4 #include<algorithm> 5 usi 阅读全文
posted @ 2012-08-28 11:36 _雨 阅读(174) 评论(0) 推荐(0)
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1698View Code 1 #include <iostream> 2 #include<cstdio> 3 #include<string.h> 4 using namespace std; 5 #define max 100000 6 int s[max*4],te[max*4]; 7 void pushup(int w) 8 { 9 s[w] = s[2*w]+s[2*w+1];10 }11 void pushdown(int w,int m)12 {13 if(t 阅读全文
posted @ 2012-08-09 23:40 _雨 阅读(182) 评论(0) 推荐(0)
摘要:http://acm.sdut.edu.cn/bbs/read.php?tid=5651。。本来只会向上更新 现在学习了如何向下更新 延迟标记法。。。使复杂度降低View Code 1 #include <iostream> 2 #include<cstdio> 3 #include<string.h> 4 using namespace std; 5 #define max 100000 6 __int64 s[max*4],te[max*4]; 7 void pushup(int w) 8 { 9 s[w] = s[2*w]+s[2*w+1];10 }1 阅读全文
posted @ 2012-08-09 23:09 _雨 阅读(164) 评论(0) 推荐(0)
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1754依次比较左右子节点 父节点存最大值View Code 1 #include <iostream> 2 #include<cstdio> 3 #include<string.h> 4 #define MAX 200000 5 using namespace std; 6 int s[MAX*4],a; 7 void push(int w) 8 { 9 if(s[2*w]>s[2*w+1])10 s[w] = s[2*w];11 else12 s[w... 阅读全文
posted @ 2012-08-09 11:55 _雨 阅读(184) 评论(0) 推荐(0)
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=4217开一个数组标记这个数是否被拿走 s[w]为区间和 当求第K小的数的时候 让他与s[w]的左右子树比较 看在哪个区间中 依次找下去 总会找到一个s[]与他相等 所对应的区间就是那个应该被拿走的值View Code 1 #include <iostream> 2 #include<cstdio> 3 #include<string.h> 4 #define MAX 262144 5 using namespace std; 6 int to[4*MAX]; 7 __int 阅读全文
posted @ 2012-08-09 10:20 _雨 阅读(202) 评论(0) 推荐(0)
摘要:http://poj.org/problem?id=2528线段树加离散化 搜了好多资料 WA了一下午终于把这题做出来了 看讨论上说这题数据有问题 这种离散化严格来说是不对的 但是这题却可以水过去 由于刚接触 就不去探索很精确的离散化的方法了 先把普通的离散化了解下就好代码View Code 1 #include <iostream> 2 #include<cstdio> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 #define N 20000 7 st 阅读全文
posted @ 2012-08-08 16:25 _雨 阅读(183) 评论(0) 推荐(0)
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=4339对线段树还是不熟悉吧 写起来挺费劲的 大体知道怎么写 还是老出错 一直纠结区间被砍开了 怎么找剩余的部分 这部分还必须是跟第一部分连着的后来想到找到第一个区间之后 以区间的r+1作为新的查找点继续递归查找犯了很二的错误 建树建小了 该是100W 折腾了差不多4小时吧View Code 1 #include<stdio.h> 2 #include<string.h> 3 struct node 4 { 5 int l,r,data; 6 }s[3000000]; 7 #define 阅读全文
posted @ 2012-08-02 18:41 _雨 阅读(257) 评论(0) 推荐(0)
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=4325多校联合3上的题 对线段树还不是太了解 只知道这道题是线段树 打的代码那叫一个纠结啊 。。交上还TLE昨天晚上仔细想了想 明白是怎么回事了 就是建一个线段树 找到指定的区间加1 询问的时候 看在哪些区间里 把这些区间都加起来w定义的int类型的 一直出错 后来一想 存不了 改了就对了View Code 1 #include<stdio.h> 2 #include<string.h> 3 #define N 100001 4 __int64 s[4*N],re; 5 void bu 阅读全文
posted @ 2012-08-01 09:37 _雨 阅读(192) 评论(0) 推荐(0)
摘要:http://poj.org/problem?id=2299求逆序数第一种做法 利用归并排序 在进行两个升序数组归并时 如果右边指针指向的那个数比左边小 那从左边那个位置到mid的数都比右边那个数大 所以比它大的数的个数就是 左边那个数到mid之间的数 依次类推View Code 1 #include <stdio.h> 2 #include <string.h> 3 long long a[500001],num,x[500001],y[500001]; 4 long long msort(long long low,long long mid,long long h 阅读全文
posted @ 2012-07-28 13:22 _雨 阅读(213) 评论(0) 推荐(0)
摘要:http://poj.org/problem?id=2777网上的一段解释经典的线段树题目。成段更新,在利用一个数组在查询顺次整段区间时,登记未曾被遮蔽到的颜色,并对其所对应的编号符号为1.而在成段更新结点时,若某区间将揭示混杂色,就让其子节点更新为它的颜色,并符号该结点。总之,对于成段更新区间属性的题目等闲用线段树来处理,利用时要保留结点属性的单一性,但更新摧毁了这种单一性时,则应递归地坚持该结点孩子的属性的单一性。只有这么,在更新垄断才不至于退化到O(n)的混杂度,保证高效率。View Code 1 #include 2 #include 3 #include 4 #inc... 阅读全文
posted @ 2012-07-27 21:48 _雨 阅读(198) 评论(0) 推荐(0)
摘要:线段树 单点更新http://acm.hdu.edu.cn/showproblem.php?pid=1166View Code 1 #include<stdio.h> 2 #include<string.h> 3 int sum[1000001]; 4 void push(int w) 5 { 6 sum[w] = sum[2*w]+sum[2*w+1];//更新节点值 7 } 8 void build(int l,int r,int w) 9 {10 if(l==r)11 {12 scanf("%d",&sum[w]);13 retu... 阅读全文
posted @ 2012-07-26 09:26 _雨 阅读(164) 评论(0) 推荐(0)
摘要:http://dongxicheng.org/structure/segment-tree/线段树,也叫区间树,是一个完全二叉树,它在各个节点保存一条线段(即“子数组”),因而常用于解决数列维护问题,它基本能保证每个操作的复杂度为O(lgN)。线段树的基本操作主要包括构造线段树,区间查询和区间修改。struct node{ int ld,rd;//左右边界 node *lc,*rc;//左右孩子 int key;//信息域 如RMQ问题中,信息域中存储的是区间最大值};建树//空树的建立,内含key值的初始化; //一般在主函数中首先调用 Node* root= buildt... 阅读全文
posted @ 2012-07-25 17:25 _雨 阅读(238) 评论(2) 推荐(0)