当前位置: 移动技术网 > IT编程>开发语言>C/C++ > skkyk:线段树浅谈

skkyk:线段树浅谈

2019年06月20日  | 移动技术网IT编程  | 我要评论

音箱报价,泡沫之夏2txt,周建畏

推荐前辈学姐博客文章,写的很细

https://www.cnblogs.com/theroadtothegold/p/6254255.html

学学半,此随笔主要是加深自己对线段树的理解

题目:洛谷p3374模(mu)板题

(话说为什么是树状数组,主要是因为我太菜了不会懒标记)

//代码中的位运算其实就是乘除2的一些操作
#include<cstdio> using namespace std; int n,m,ans; struct node { int left,right,num; }tree[500000*4+5];//经典的四倍空间,我也不知道为什么 int input[500000+5]; void build(int index,int l,int r)//建树,一棵满二叉树 { tree[index].left=l,tree[index].right=r; if(l==r) { tree[index].num=input[l]; return ; } int mid=(l+r)>>1; build(index<<1,l,mid);build(index<<1|1,mid+1,r); tree[index].num=tree[index<<1].num+tree[index<<1|1].num; } void add(int index,int target,int k)//单点修改,变量是序号、目标、修改值 { tree[index].num+=k;//对于每个可以递归到的点都是包含目标target这个点的集合,都要一并加上k if(tree[index].left==tree[index].right)//单点集合返回 return ; if(target<=tree[index<<1].right) add(index<<1,target,k); if(target>=tree[index<<1|1].left) add(index<<1|1,target,k);//两个if语句都是判断是否存在交集,是则进行下一层 } void query(int index,int l,int r)//区间求和(区间查询) { if(tree[index].right<=r&&tree[index].left>=l) { ans+=tree[index].num;//对于区间的子集累计答案 return ;//避免累计区间子集的区间子集 ??exm } if(tree[index].right==tree[index].left) return ; if(tree[index<<1].right>=l) query(index<<1,l,r); if(tree[index<<1|1].left<=r) query(index<<1|1,l,r);//同为寻找交集 return ; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",input+i); build(1,1,n);//建树 for(int i=1,a,x,y;i<=m;i++) { scanf("%d%d%d",&a,&x,&y); if(a==1) add(1,x,y);//单点修改 if(a==2) { ans=0; query(1,x,y);//区间查询 printf("%d\n",ans); } }
  return 0; }

等改天问一下学长们懒标记的具体

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网