ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

线段树——内存池

2020-07-05 15:07:38  阅读:254  来源: 互联网

标签:return rs 线段 tag ls const ll 内存


#洛谷P2574

new为C++中提供的一种“动态内存分配”机制,使得程序可以在运行期间,根据实际需求,要求操作系统临时分配一片内存空间用于存放数据;

通过new运算符来实现;

但是new的时间复杂度并不小,所以需要找一个方法来优化(或替代)new,来加快程序运行的速度

(顺便A道黄题)

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<math.h>
  5 #include<cstring>
  6 #define ll long long
  7 using namespace std;
  8 
  9 const ll maxn=2e5+10;
 10 ll n,m;
 11 ll a[maxn];
 12 char x[maxn];
 13 
 14 struct node
 15 {
 16     ll v;
 17     ll tag;
 18     ll l,r;
 19     node *ls,*rs;
 20     
 21     inline void pushup()
 22     {
 23         v=ls->v+rs->v;
 24     }
 25     
 26     inline void maketag()
 27     {
 28         v=(r-l+1)-v;//每进行一次修改,就是把0和1的数量交换,故用当前总数量减去当前1的数量,即为变换前0的数量,亦为变换后1的数量,每进行两次修改,就相当于没有进行修改操作
 29         tag^=1;//同一个数进行两次异或运算即为原数,故用tag作为是否进行异或的标记
 30     }
 31     
 32     inline void pushdown()//懒标记下传
 33     {
 34         if(!tag) return ;
 35         ls->maketag();
 36         rs->maketag();
 37         tag=0;
 38     }
 39     
 40     inline bool inrange(const ll L,const ll R)
 41     {
 42         return (L<=l)&&(r<=R);
 43     }
 44     inline bool outrange(const ll L,const ll R)
 45     {
 46         return (l>R)||(r<L);
 47     }
 48     
 49     inline void upd(const ll L,const ll R)//区间修改
 50     {
 51         if(inrange(L,R))
 52         {
 53             maketag();
 54         }
 55         else if(!outrange(L,R))
 56         {
 57             pushdown();
 58             ls->upd(L,R);
 59             rs->upd(L,R);
 60             pushup();
 61         }
 62     }
 63     inline ll qry(const ll L,const ll R)//区间查询
 64     {
 65         if(inrange(L,R)) return v;
 66         else if(outrange(L,R)) return 0;
 67         else
 68         {
 69             pushdown();
 70             return ls->qry(L,R)+rs->qry(L,R);
 71         }
 72     }
 73 } mem[(maxn<<1)+10];//线段树中最多一共有2n-1个节点,故将内存池空间扩大2倍
 74 
 75 node *pool=mem;//pool为一个静态内存池,指向Mem,当需要建立新的节点时,则让指针取得pool中的地址,借以替代new
 76 node *New(const ll L,const ll R)
 77 {
 78     node *u=pool++;
 79     
 80     u->l=L;
 81     u->r=R;
 82     u->tag=0;
 83     
 84     if(L==R)//该节点为叶子结点
 85     {
 86         u->ls=u->rs=NULL;
 87         u->v=a[L];
 88     }
 89     else//递归建树
 90     {
 91         ll M=(L+R)>>1;
 92         u->ls=New(L,M);
 93         u->rs=New(M+1,R);
 94         u->pushup();
 95     }
 96     return u;
 97 }
 98 
 99 
100 int main(void)
101 {
102     scanf("%lld%lld",&n,&m);
103     scanf("%s",x);
104     for(int i=1;i<=n;i++)
105     {
106         a[i]=x[i-1]-'0';
107     }
108     node *rot=New(1,n);
109     for(ll op,l,r;m;m--)
110     {
111         scanf("%lld%lld%lld",&op,&l,&r);
112         if(op==0)
113         {
114             rot->upd(l,r);//修改
115         }
116         else
117         {
118             printf("%lld\n",rot->qry(l,r));//查询
119         }
120     }
121     return 0;
122 }

 

标签:return,rs,线段,tag,ls,const,ll,内存
来源: https://www.cnblogs.com/jd1412/p/13246053.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有