非递归线段树

  支持区间加,区间查询最大值

模板:

  1 struct Segment_tree
  2 {
  3     int size;
  4     int *node;
  5     void build(int n)
  6     {
  7         n+=4;
  8         size=1;
  9         while(size<n)
 10             size<<=1;
 11         node=new int[size+size+4];
 12     }
 13     void updata(int pos)
 14     {
 15         int A=max(node[pos<<1],node[pos<<1^1]);
 16         node[pos<<1]-=A;
 17         node[pos<<1^1]-=A;
 18         node[pos]+=A;
 19     }
 20     void build(int n,int arr[])
 21     {
 22         build(n);
 23         int i;
 24         memset(node,0,8*size);
 25         for(i=1; i<=n; i++)
 26         {
 27             node[i+size]=arr[i];
 28             //printf("%d ",arr[i]);
 29         }
 30         //printf("size =%d",size);
 31         //puts("");
 32         for(i=size-1; i>0; i--)
 33         {
 34             updata(i);
 35         }
 36     }
 37     void add(int l,int r,int d)
 38     {
 39         l+=size-1;
 40         r+=size+1;
 41         int A;
 42         for(; r^l^1; l>>=1,r>>=1 )
 43         {
 44             if(~l&1)
 45                 node[l^1]+=d;
 46             if(r&1)
 47                 node[r^1]+=d;
 48             updata(l>>1);
 49             updata(r>>1);
 50         }
 51         while(l>1)
 52         {
 53             updata(l>>=1);
 54         }
 55     }
 56     int RMQ(int l,int r)
 57     {
 58         l+=size;
 59         r+=size;
 60         int ans,lans=0,rans=0;
 61         if(l!=r)
 62         {
 63             for(; r^l^1; l>>=1,r>>=1 )
 64             {
 65                 lans+=node[l];
 66                 rans+=node[r];
 67                 if(~l&1)
 68                     lans=max(lans,node[l^1]);
 69                 if(r&1)
 70                     rans=max(rans,node[r^1]);
 71             }
 72         }
 73         ans=max(lans+node[l],rans+node[r]);
 74         while(l>1)
 75         {
 76             ans+=node[l>>=1];
 77         }
 78         return ans;
 79     }
 80     void put()
 81     {
 82         int i=1,j=1,s=size*4,k,len=3;
 83         for(i=1; i<=2*size-1; i++)
 84         {
 85             if(i==j)
 86             {
 87                 puts("");
 88                 j<<=1;
 89                 s>>=1;
 90                 for(k=0; k<len*(s/2-1); k++)
 91                     printf(" ");
 92
 93             }
 94             printf("%3d",node[i]);
 95             for(k=0; k<len*(s-1); k++)
 96                 printf(" ");
 97
 98         }
 99         puts("");
100     }
101 } tree;
时间: 2024-08-17 13:11:51

非递归线段树的相关文章

非递归线段树专题

学习了自底向上的非递归线段树,深感精妙!! 大牛的博客:http://blog.csdn.net/zearot/article/details/48299459 张坤玮---统计的力量 The Union of k-Segments CodeForces - 612D 题意:求被覆盖k次及以上的点或者线段. 看到别人直接用扫描线写的,更方便一些. 不过拿来练习线段树也不错. 1 #include <bits/stdc++.h> 2 using namespace std; 3 const in

非递归线段树区间修改区间求和的两种实现(以POJ 3468为例)

题意:就是一个数列,支持  查询区间和  以及  区间内的数都加上 C . 递归线段树很好写,就不讲了. 递归版本        : 内存:6500K   时间:2.6 秒 非递归版本一: 内存:4272K   时间:1.1秒 非递归版本二: 内存:4272K   时间:1.3秒 -------------------------------------------------------------------------------------------------------------

(源码,具体的细节请查阅相关资料)哈弗曼树的构造以及非递归遍历树

写了一点haffman树的创建和二叉树的非递归遍历. 如果编写代码的时候出现了,思维断点,可以借鉴一下, 避免浪费一些不必要的时间. 我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占 位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我 是占位符我是占位符我是占位符我是占位符我是占位符我是 占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符我是占位符

【模板】 递归线段树 [2017年五月计划 清北学堂51精英班Day4]

P3372 [模板]线段树 1 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k 操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的

hdu 3887 Counting Offspring(DFS序【非递归】+树状数组)

题意: N个点形成一棵树.给出根结点P还有树结构的信息. 输出每个点的F[i].F[i]:以i为根的所有子结点中编号比i小的数的个数. 0<n<=10^5 思路: 方法一:直接DFS,进入结点x时记录一下比x小的数的个数.出来x时记录一下比x小的数的个数.相减就是F[x].结合树状数组. 方法二:写下DFS序.对DFS序列建线段树.然后从小到大对结点进行插入.用线段树统计. 代码:(方法一) int const N=1e5+5; int n,p; vector<int> G[N];

非递归实现树的遍历

[代码] #include <iostream> #include <stack> using namespace std; typedef struct Node{ char key; struct Node *lchild, *rchild; }*Tree, TNode; void PreOrder(Tree T) //先序遍历 { if (T == NULL) return; TNode *curr = T; //TNode *tmp; stack<Tree> s

非递归实现树的前序遍历

/*binary-tree-postorder-traversal*/ /***************************/ /* Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary tree{1,#,2,3}, 1 2 / 3 return[3,2,1]. Note: Recursive solution is trivial, could

BZOJ 3022 [Balkan2012]The Best Teams(扫描线+线段树)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3022 [题目大意] 给定n个球员,第i个球员年龄为AGEi,水平为SKILLi. 没有任何两个球员的水平相同.将这些球员按水平排序, 对于一次比赛,你需要选择若干个球员去比赛,但不能同时选择两个水平相邻的球员. m次询问,每次给定a和k,表示要在年龄不超过a的球员中选择不超过k个球员, 请计算skill和的最大值. [题解] 对于询问年龄的限制,我们可以通过扫描线来处理. 我们将所有

线段树详解 (原理,实现与应用)

线段树详解 By 岩之痕 目录: 一:综述 二:原理 三:递归实现 四:非递归原理 五:非递归实现 六:线段树解题模型 七:扫描线 八:可持久化 (主席树) 九:练习题 一:综述 假设有编号从1到n的n个点,每个点都存了一些信息,用[L,R]表示下标从L到R的这些点. 线段树的用处就是,对编号连续的一些点进行修改或者统计操作,修改和统计的复杂度都是O(log2(n)). 线段树的原理,就是,将[1,n]分解成若干特定的子区间(数量不超过4*n),然后,将每个区间[L,R]都分解为 少量特定的子区