简单的线段树
来源:互联网 发布:centos配置rsyslog 编辑:程序博客网 时间:2024/06/04 19:43
前言
线段树想必大家再熟悉不过了,说实话敲线段树的模板还是很享受的(温馨提示:不要被数据结构所驾驭了)。
这里,蒟蒻我就简要说一下鄙人的线段树的一些简单功能:支持单点、区间更新,求单点权值,区间求和、最值。
struct Tree{ #define lson L,mid,p<<1 #define rson mid+1,R,p<<1|1 #define family tree[p],tree[p<<1],tree[p<<1|1] #define root 1,n,1 struct node{ int L,R; int sum,add; int Mx,Mn; }tree[N<<2]; void Up(node &A,node L,node R){ A.sum=L.sum+R.sum; A.Mx=max(L.Mx,R.Mx); A.Mn=min(L.Mn,R.Mn); } void Down(node &A,node &L,node &R){ int &t=A.add; if(!t)return; L.add+=t; R.add+=t; L.sum+=t*(L.R-L.L+1); R.sum+=t*(R.R-R.L+1); t=0; } void build(int L,int R,int p){ tree[p].L=L,tree[p].R=R; tree[p].sum=tree[p].add=0; if(L==R){// tree[p].sum=A[L]; return; } int mid=(L+R)>>1; build(lson),build(rson); Up(family); } void update_one(int x,int res,int p){ if(tree[p].L==tree[p].R){ tree[p].sum+=res; return; } int mid=(tree[p].L+tree[p].R)>>1; if(x<=mid)update_one(x,res,p<<1); else update_one(x,res,p<<1|1); Up(family); } void update_interval(int L,int R,int p,int res){ if(tree[p].L==L && tree[p].R==R){ tree[p].add+=res; tree[p].sum+=1LL*res*(R-L+1); return; } Down(family); int mid=(tree[p].L+tree[p].R)>>1; if(R<=mid)update_interval(L,R,p<<1,res); else if(L>mid)update_interval(L,R,p<<1|1,res); else update_interval(lson,res),update_interval(rson,res); Up(family); } //注意求单点只需要沿途加上sum即可,不用Down int query_one(int x,int p){ int mid=(tree[p].L+tree[p].R)>>1; if(x<=mid)return tree[p].sum+query_one(x,p<<1); else return tree[p].sum+query_one(x,p<<1|1); } int query_interval(int L,int R,int p){ if(tree[p].L==L && tree[p].R==R)return tree[p].sum; Down(family); int mid=(tree[p].L+tree[p].R)>>1; if(R<=mid)return query_interval(L,R,p<<1); else if(L>mid)return query_interval(L,R,p<<1|1); else return query_interval(lson)+query_interval(rson); } int query_Max(int L,int R,int p){ if(tree[p].L==L && tree[p].R==R)return tree[p].Mx; int mid=(tree[p].L+tree[p].R)>>1; if(R<=mid)return query_Max(L,R,p<<1); else if(L>mid)return query_Max(L,R,p<<1|1); else return max(query_Max(lson),query_Max(rson)); } int query_Min(int L,int R,int p){ if(tree[p].L==L && tree[p].R==R)return tree[p].Mn; int mid=(tree[p].L+tree[p].R)>>1; if(R<=mid)return query_Min(L,R,p<<1); else if(L>mid)return query_Min(L,R,p<<1|1); else return min(query_Min(lson),query_Min(rson)); }}Tree;
小结:
线段树是一个非常好用的东西,是常用于维护区间的某些值的数据结构之一。
阅读全文
0 0
- 简单的线段树
- 线段树的简单应用
- hdu简单的线段树
- 线段树 HDU 1754 最简单的线段树
- hdu 1754 简单的线段树
- bzoj 1012 简单的线段树
- hdu1754 简单的线段树单点更新
- 简单线段树总结
- hdu1166 简单线段树
- hdu1166--简单线段树
- hdu1166简单线段树
- 线段树简单题
- 简单线段树模板
- 简单线段树模板
- 线段树简单实现
- 线段树的入门-Poj2528(简单线段树和简单离散化)
- 线段树的简单应用;火车订票;线段树用起来太灵活了!;
- hdu1698(线段树,简单的成段更新)
- 一站式解决java web乱码问题
- PAT1002 写出这个数 初学者
- 【转载】希尔排序
- poj2778 DNA Sequence (AC自动机+矩阵乘法)
- ADV-169 士兵排队问题
- 简单的线段树
- 用函数对象表示策略。
- android隐藏apk方式以及apk之间的启动方式
- 【网易】最长公共子括号序列
- 使用Redis SETNX 命令实现分布式锁
- SpringMvc 拦截器
- markdown的流程图实现和代码语法着色
- if语句
- 20171107