[模板]线段树
来源:互联网 发布:佛山房产网签数据 编辑:程序博客网 时间:2024/06/06 17:15
codevs4927
1、注意代码是左闭右闭的线段树,mid在左区间内
2、打权值线段树时注意线段树右端点大于最大值
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#define L(w) w << 1#define R(w) w << 1|1#define INF 1061109567typedef long long LL;using namespace std;const int MAXN = 200000 + 50;int L[MAXN << 2],R[MAXN << 2],maxn[MAXN << 2],minx[MAXN << 2],M1[MAXN << 2],M2[MAXN << 2];LL sum[MAXN << 2];int A[MAXN];void update(int w){ sum[w] = sum[L(w)] + sum[R(w)]; minx[w] = min(minx[L(w)],minx[R(w)]); maxn[w] = max(maxn[L(w)],maxn[R(w)]);}void spread1(int w){ if(M1[w] == -1)return; int m = M1[w]; M1[w] = -1; minx[L(w)] = maxn[L(w)] = m; minx[R(w)] = maxn[R(w)] = m; sum[L(w)] = m*(R[L(w)] - L[L(w)] + 1); sum[R(w)] = m*(R[R(w)] - L[R(w)] + 1); M2[L(w)] = M2[R(w)] = 0; M1[L(w)] = M1[R(w)] = m;}void spread(int w){ if(M1[w] != -1){ spread1(w); } int m = M2[w]; if(!m)return; M2[w] = 0; spread1(L(w)); spread1(R(w)); maxn[L(w)] += m; maxn[R(w)] += m; minx[L(w)] += m; minx[R(w)] += m; sum[L(w)] += m*(R[L(w)] - L[L(w)] + 1); sum[R(w)] += m*(R[R(w)] - L[R(w)] + 1); M2[L(w)] += m; M2[R(w)] += m;}void build(int w,int l,int r){ L[w] = l;R[w] = r; if(l == r){ sum[w] = minx[w] = maxn[w] = A[l]; return; } int mid = l + r >> 1; build(L(w),l,mid); build(R(w),mid + 1,r); update(w);}void cover(int w,int l,int r,int v){ if(L[w] == l && R[w] == r){ M2[w] = 0; M1[w] = v; minx[w] = maxn[w] = v; sum[w] = v*(R[w] - L[w] + 1); return; } spread(w);//重置前,先下放标记 int mid = L[w] + R[w] >> 1; if(r <= mid)cover(L(w),l,r,v); else if(l > mid)cover(R(w),l,r,v); else cover(L(w),l,mid,v),cover(R(w),mid + 1,r,v); update(w);}void add(int w,int l,int r,int v){ if(L[w] == l && R[w] == r){ spread1(w); M2[w] += v; minx[w] += v; maxn[w] += v; sum[w] += v*(R[w] - L[w] + 1); return; } spread(w); int mid = L[w] + R[w] >> 1; if(r <= mid)add(L(w),l,r,v); else if(l > mid)add(R(w),l,r,v); else add(L(w),l,mid,v),add(R(w),mid + 1,r,v); update(w);}LL ask_sum(int w,int l,int r){ if(L[w] == l && R[w] == r){ return sum[w]; } spread(w); LL ans = 0; int mid = L[w] + R[w] >> 1; if(r <= mid)ans = ask_sum(L(w),l,r); else if(l > mid)ans = ask_sum(R(w),l,r); else ans = ask_sum(L(w),l,mid) + ask_sum(R(w),mid + 1,r); return ans;}int ask_max(int w,int l,int r){ if(L[w] == l && R[w] == r){ return maxn[w]; } spread(w); int mid = L[w] + R[w] >> 1; int ans = -INF; if(r <= mid)ans = ask_max(L(w),l,r); else if(l > mid)ans = ask_max(R(w),l,r); else ans = max(ask_max(L(w),l,mid),ask_max(R(w),mid + 1,r)); return ans;}int ask_min(int w,int l,int r){ if(L[w] == l && R[w] == r){ return minx[w]; } spread(w); int mid = L[w] + R[w] >> 1; int ans = INF; if(r <= mid)ans = ask_min(L(w),l,r); else if(l > mid)ans = ask_min(R(w),l,r); else ans = min(ask_min(L(w),l,mid),ask_min(R(w),mid + 1,r)); return ans;}int n,m,a,b,c;string s;int main(){ memset(M1,-1,sizeof(M1)); scanf("%d%d",&n,&m); for(int i = 1;i <= n;i ++){ scanf("%d",&A[i]); } build(1,1,n); for(int i = 1;i <= m;i ++){ cin >> s; if(s == "add"){ scanf("%d%d%d",&a,&b,&c); add(1,a,b,c); } else if(s == "set"){ scanf("%d%d%d",&a,&b,&c); cover(1,a,b,c); } else if(s == "sum"){ scanf("%d%d",&a,&b); if(a > b)swap(a,b); printf("%lld\n",ask_sum(1,a,b)); } else if(s == "max"){ scanf("%d%d",&a,&b); printf("%d\n",ask_max(1,a,b)); } else if(s == "min"){ scanf("%d%d",&a,&b); printf("%d\n",ask_min(1,a,b)); } } return 0;}
阅读全文
0 0
- ACM 线段树模板(模板)
- 线段树模板
- hdu_1166_线段树模板
- 线段树模板
- 线段树模板 poj2777
- 线段树模板
- 线段树模板
- 线段树-模板
- 线段树模板
- 线段树模板
- 线段树模板
- Hdu1166-- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- 第11周项目3-图遍历算法实现
- 讲一件怎么妙用eoLinker进行导入导出数据库
- 2017.11.5
- C++ 遍历目录文件及打印文件和其后缀
- 慕课网《HTML+CSS基础课程》笔记总结(八)
- [模板]线段树
- 03oracle学习笔记
- 上半年公有云增长28.6% ,IDC说再不用公有云就没有创新
- netlink demo
- Uint10
- 阻止表单以回车方式提交
- Deterministic Policy Gradient Algorithms
- 最强PostMan使用教程(1)
- PaaS Innovation 2017开幕在即,约不