数据结构模板
来源:互联网 发布:美国人口增长 知乎 编辑:程序博客网 时间:2024/06/07 19:33
以下数据类型均以double作为value_type,使用时根据实际情况修改为其他类型。
二叉索引树
struct FenwickTree:vector<double>{ explicit FenwickTree(int k)//默认初始化一个能保存k个元素的空树状数组 { assign(k+1,0);//有效下标从1开始,0仅作逻辑用处 } int lowbit(int k) { return k&-k;//也可写作x&(x^(x–1)) } double sum(int k)//求第1个元素到第k个元素的和 { if(k<=0)return 0; return sum(k-lowbit(k))+(*this)[k]; } double query(int l,int r)//区间求和 { return sum(r)-sum(l-1); } void add(int k,double w)//为节点k加上w { if(k>=size())return; (*this)[k]+=w; add(k+lowbit(k),w); }};
静态RMQ
struct SparseTable_RMQ { vector<vector<double> > d; SparseTable_RMQ(const vector<double> &v) { d.assign(v.size(),vector<double>()); for(int i=0; i!=v.size(); ++i) d[i].push_back(v[i]); for(int j=0; (1<<j)<=v.size(); ++j) for(int i=0; (1<<j)+i-1<v.size(); ++i) d[i].push_back(min(d[i][j-1], d[i+(1<<j-1)][j-1])); } double query(int l,int r) { int k=0; while((1<<k+1)<=r-l+1) ++k; return min(d[l][k],d[r-(1<<k)+1][k]); }};
线段树
区间增加
struct SegTree1{ vector<double> sumv,minv,addv; double inf=1e9,_min,_sum; int last; explicit SegTree1(int _n) { last=_n;//有效下标从1开始,0仅作逻辑用处 addv.assign(2*last,0); sumv.assign(2*last,0); minv.assign(2*last,inf); } void add(int pl,int pr,double pv) { add(pl,pr,pv,1,1,last); } void query(int ql,int qr) { _sum=0; _min=inf; query(ql,qr,0,1,1,last); } void add(int pl,int pr,double pv, int k,int l,int r) { if(pl<=l&&r<=pr) addv[k]+=pv; else { int lc=k*2,rc=k*2+1,m=l+(r-l)/2; if(pl<=m)add(pl,pr,pv,lc,l,m); if(m<pr)add(pl,pr,pv,rc,m+1,r); } maintain(k,l,r); } void query(int ql,int qr,double add,//当前所有节点祖先add之和 int k,int l,int r) { if(ql<=l&&r<=qr) { _sum+=sumv[k]+add*(r-l+1); _min=min(_min,minv[k]+add); return; } int lc=k*2,rc=k*2+1,m=l+(r-l)/2; if(ql<=m)query(ql,qr,add+addv[k],lc,l,m); if(m<qr)query(ql,qr,add+addv[k],rc,m+1,r); } void maintain(int k,int l,int r)//维护节点k { minv[k]=addv[k]; sumv[k]=addv[k]*(r-l+1); if(r>l) { int lc=k*2,rc=k*2+1; sumv[k]+=sumv[lc]+sumv[rc]; minv[k]+=min(minv[lc],minv[rc]); } }};
区间修改
struct SegTree2{ vector<double> sumv,minv,setv; double inf=1e9,_min,_sum; int last; explicit SegTree2(int _n) { last=_n;//有效下标从1开始,0仅作逻辑用处 setv.assign(2*last,inf); sumv.assign(2*last,0); minv.assign(2*last,inf); } void update(int pl,int pr,double pv) { return update(pl,pr,pv,1,1,last); } void query(int ql,int qr) { _sum=0; _min=inf; query(ql,qr,1,1,last); } void update(int pl,int pr,double pv, int k,int l,int r) { if(pl<=l&&r<=pr) setv[k]=pv; else { int lc=k*2,rc=k*2+1,m=l+(r-l)/2; if(setv[k]!=inf)//结点有标记,向下传递 { setv[lc]=setv[rc]=setv[k]; setv[k]=inf;//清除本节点标记 } if(pl<=m)update(pl,pr,pv,lc,l,m); else maintain(lc,l,m); if(m<pr)update(pl,pr,pv,rc,m+1,r); else maintain(rc,m+1,r); } maintain(k,l,r); } void query(int ql,int qr, int k,int l,int r) { if(setv[k]!=inf)//递归边界1:有set标记 { _sum+=setv[k]*(min(r,qr)-max(l,ql)+1); _min=min(_min,setv[k]); } else if(ql<=l&&r<=qr)//递归边界2:边界区间,没有被set操作影响 { _sum+=sumv[k]; _min=min(_min,minv[k]); } else { int lc=k*2,rc=k*2+1,m=l+(r-l)/2; if(ql<=m)query(ql,qr,lc,l,m); if(m<qr)query(ql,qr,rc,m+1,r); } } void maintain(int k,int l,int r)//维护节点k { minv[k]=setv[k]; sumv[k]=setv[k]*(r-l+1); if(r>l) { int lc=k*2,rc=k*2+1; sumv[k]+=sumv[lc]+sumv[rc]; minv[k]+=min(minv[lc],minv[rc]); } }};
阅读全文
0 0
- 数据结构模板
- 数据结构模板
- 模板-数据结构
- [模板] 数据结构
- 模板(数据结构)
- 数据结构模板
- 数据结构模板
- 数据结构模板
- 数据结构模板
- 【LaTeX】CTeX数据结构模板
- 数据结构 字典树模板
- 数据结构--AC自动机--模板
- 模板:(数据结构:线段树)
- 数据结构---邻接表(模板)
- 数据结构---各种树模板
- c++数据结构模板
- 数据结构中链表模板
- 数据结构—KMP模板
- OpenCV学习2 模板匹配
- 使用函数的调用来依次输入三个数的大小
- 【Scikit-Learn 中文文档】新异类和异常值检测
- CodeForces
- spring异常记录
- 数据结构模板
- 苹果in-house包内网网页安装
- 机器学习基础概念和名词
- C#中的字符串转换为数字
- linux的进程优先级
- 多路型DMA接口的工作原理
- 蓝桥杯 算法训练 阿尔法乘积
- 如何将本机的软链接一同远程复制到远程主机,并且还是以软链接的形式存在
- Homebrew使用详解,macOS的第二个Mac App Store !