XTU1238:Segment Tree(线段树区间更新)
来源:互联网 发布:淘宝篮球鞋进货渠道 编辑:程序博客网 时间:2024/06/03 12:29
Segment Tree
Accepted : 98 Submit : 545Time Limit : 9000 MS Memory Limit : 65536 KBSegment Tree
Problem Description:
A contest is not integrity without problems about data structure.
There is an array a[1],a[2],…,a[n]. And q questions of the following 4 types:- 1 l r c - Update a[k] with a[k]+c for all l≤k≤r
- 2 l r c - Update a[k] with min{a[k],c} for all l≤k≤r;
- 3 l r c - Update a[k] with max{a[k],c} for all l≤k≤r;
- 4 l r - Ask for min{a[k]:l≤k≤r} and max{a[k]:l≤k≤r}.
Input
The first line contains a integer T(no more than 5) which represents the number of test cases.
For each test case, the first line contains 2 integers n,q (1≤n,q≤200000).
The second line contains n integers a1,a2,…,an which indicates the initial values of the array (|ai|≤).
Each of the following q lines contains an integer t which denotes the type of i-th question. If t=1,2,3, 3 integers l,r,c follows. If t=4, 2 integers l,r follows. (1≤ti≤4,1≤li≤ri≤n)
If t=1, |ci|≤2000;
If t=2,3, |ci|≤10^9.
Output
For each question of type 4, output two integers denote the minimum and the maximum.
Sample Input
1
1 1
1
4 1 1
Sample Output
1 1
题目链接:http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1238
题目大意:自己看;
题目分析:线段树区间更新,区间求值;
我的初始错误代码:
#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;typedef long long ll;const int maxn=222222;ll minv[maxn*8],maxv[maxn*8],num[maxn*8],smin[maxn*8],smax[maxn*8],addv[maxn*8];int n,p;ll _maxv,_minv;void maintain(int o,int l,int r){ int lc=o<<1,rc=o<<1|1; if(l==r) return ; minv[o]=min(minv[lc],minv[rc]); maxv[o]=max(maxv[lc],maxv[rc]);}void build(int o,int l,int r){ int lc=o<<1,rc=o<<1|1; if(l==r) { minv[o]=maxv[o]=num[l]; return ; } int m=(l+r)>>1; build(lc,l,m); build(rc,m+1,r); maintain(o,l,r);}void pushdown(int o,int l,int r){ if(l==r) return ; int lc=o<<1,rc=o<<1|1; if(addv[o]) { minv[lc]+=addv[o]; minv[rc]+=addv[o]; addv[lc]+=addv[o]; addv[rc]+=addv[o]; maxv[lc]+=addv[o]; maxv[rc]+=addv[o]; addv[o]=0; } if(smax[o]) { smax[lc]=smax[rc]=smax[o]; minv[lc]=max(minv[lc],smax[o]); minv[rc]=max(minv[rc],smax[o]); maxv[rc]=max(maxv[rc],smax[o]); maxv[lc]=max(maxv[lc],smax[o]); smax[o]=0; } if(smin[o]) { smin[lc]=smin[rc]=smin[o]; minv[lc]=min(minv[lc],smin[o]); minv[rc]=min(minv[rc],smin[o]); maxv[rc]=min(maxv[rc],smin[o]); maxv[lc]=min(maxv[lc],smin[o]); smin[o]=0; }}void unreduce(int o,int l,int r,int L,int R,ll c){ int m=(l+r)>>1; int lc=o<<1,rc=o<<1|1; pushdown(o,l,r); if(l>=L&&r<=R) { smax[o]=c; minv[o]=max(minv[o],c); maxv[o]=max(maxv[o],c); return ; } if(L<=m) unreduce(lc,l,m,L,R,c); if(R>m) unreduce(rc,m+1,r,L,R,c); maintain(o,l,r);}void reduce(int o,int l,int r,int L,int R,ll c){ int m=(l+r)>>1; int lc=o<<1,rc=o<<1|1; pushdown(o,l,r); if(l>=L&&r<=R) { smin[o]=c; minv[o]=min(minv[o],c); maxv[o]=min(maxv[o],c); return ; } if(L<=m) reduce(lc,l,m,L,R,c); if(R>m) reduce(rc,m+1,r,L,R,c); maintain(o,l,r);}void add(int o,int l,int r,int L,int R,ll c){ int m=(l+r)>>1; int lc=o<<1,rc=o<<1|1; pushdown(o,l,r); if(l>=L&&r<=R) { addv[o]+=c; minv[o]+=c; maxv[o]+=c; return ; } if(L<=m) add(lc,l,m,L,R,c); if(R>m) add(rc,m+1,r,L,R,c); maintain(o,l,r);}void query(int o,int l,int r,int L,int R){ int m=(l+r)>>1; int lc=o<<1,rc=o<<1|1; pushdown(o,l,r); if(l>=L&&r<=R) { _minv=min(_minv,minv[o]); _maxv=max(_maxv,maxv[o]); return ; } if(L<=m) query(lc,l,m,L,R); if(R>m) query(rc,m+1,r,L,R); maintain(o,l,r);}int main(){ int T; while(scanf("%d",&T)!=EOF) while(T--) { memset(addv,0,sizeof(addv)); memset(smin,0,sizeof(smin)); memset(smax,0,sizeof(smax)); scanf("%d%d",&n,&p); for(int i=1;i<=n;i++) { scanf("%I64d",&num[i]); } build(1,1,n); int l,r; ll c; for(int i=0;i<p;i++) { int t; scanf("%d%d%d",&t,&l,&r); if(t==4) { _minv=1e12+7; _maxv=-1e12+7; query(1,1,n,l,r); printf("%I64d %I64d\n",_minv,_maxv); continue; } scanf("%I64d",&c); if(t==1) { add(1,1,n,l,r,c); } if(t==2) { reduce(1,1,n,l,r,c); } if(t==3) { unreduce(1,1,n,l,r,c); } } } return 0;}
这份代码错误的地方有:
当操作2,3时,有覆盖操作;
比如有smax[lr]本身有值的时候,再赋予smax[lc]值时会产生覆盖,造成错误;
参考修改代码:
#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;typedef long long ll;const int maxn=222222;ll minv[maxn*8],maxv[maxn*8],num[maxn*8],addv[maxn*8];int n,p;ll _maxv,_minv;void maintain(int o,int l,int r){ int lc=o<<1,rc=o<<1|1; if(l==r) return ; minv[o]=min(minv[lc],minv[rc]); maxv[o]=max(maxv[lc],maxv[rc]);}void build(int o,int l,int r){ int lc=o<<1,rc=o<<1|1; if(l==r) { minv[o]=maxv[o]=num[l]; return ; } int m=(l+r)>>1; build(lc,l,m); build(rc,m+1,r); maintain(o,l,r);}void pushdown(int o,int l,int r){ int lc=o<<1,rc=lc+1; if(addv[o]) { minv[lc]+=addv[o]; minv[rc]+=addv[o]; addv[lc]+=addv[o]; addv[rc]+=addv[o]; maxv[lc]+=addv[o]; maxv[rc]+=addv[o]; addv[o]=0; } minv[lc]=max(minv[o],minv[lc]);minv[lc]=min(maxv[o],minv[lc]); maxv[lc]=min(maxv[o],maxv[lc]);maxv[lc]=max(minv[o],maxv[lc]); maxv[rc]=min(maxv[o],maxv[rc]);maxv[rc]=max(minv[o],maxv[rc]); minv[rc]=max(minv[o],minv[rc]);minv[rc]=min(maxv[o],minv[rc]);}void unreduce(int o,int l,int r,int L,int R,ll c){ int m=(l+r)>>1; int lc=o<<1,rc=o<<1|1; if(l>=L&&r<=R) { maxv[o]=max(maxv[o],c); minv[o]=max(minv[o],c); return ; } pushdown(o,l,r); if(L<=m) unreduce(lc,l,m,L,R,c); if(R>m) unreduce(rc,m+1,r,L,R,c); maintain(o,l,r);}void reduce(int o,int l,int r,int L,int R,ll c){ int m=(l+r)>>1; int lc=o<<1,rc=o<<1|1; if(l>=L&&r<=R) { minv[o]=min(minv[o],c); maxv[o]=min(maxv[o],c); return ; } pushdown(o,l,r); if(L<=m) reduce(lc,l,m,L,R,c); if(R>m) reduce(rc,m+1,r,L,R,c); maintain(o,l,r);}void add(int o,int l,int r,int L,int R,ll c){ int m=(l+r)>>1; int lc=o<<1,rc=o<<1|1; if(l>=L&&r<=R) { addv[o]+=c; minv[o]+=c; maxv[o]+=c; return ; } pushdown(o,l,r); if(L<=m) add(lc,l,m,L,R,c); if(R>m) add(rc,m+1,r,L,R,c); maintain(o,l,r);}void query(int o,int l,int r,int L,int R){ int m=(l+r)>>1; int lc=o<<1,rc=o<<1|1; if(l>=L&&r<=R) { _minv=min(_minv,minv[o]); _maxv=max(_maxv,maxv[o]); return ; } pushdown(o,l,r); if(L<=m) query(lc,l,m,L,R); if(R>m) query(rc,m+1,r,L,R); maintain(o,l,r);}int main(){ int T; while(scanf("%d",&T)!=EOF) while(T--) { memset(addv,0,sizeof(addv)); scanf("%d%d",&n,&p); for(int i=1;i<=n;i++) { scanf("%I64d",&num[i]); } build(1,1,n); int l,r; ll c; for(int i=0;i<p;i++) { int t; scanf("%d%d%d",&t,&l,&r); if(t==4) { _minv=1e12+7; _maxv=-1e12+7; query(1,1,n,l,r); printf("%I64d %I64d\n",_minv,_maxv); continue; } scanf("%I64d",&c); if(t==1) { add(1,1,n,l,r,c); } if(t==2) { reduce(1,1,n,l,r,c); } if(t==3) { unreduce(1,1,n,l,r,c); } } }dai return 0;}
- XTU1238:Segment Tree(线段树区间更新)
- XTU1238 Segment Tree (线段树·区间最值更新)
- XTU1238:Segment Tree(线段树)
- XTU1238:Segment Tree(线段树)
- CF242:XOR on Segment(线段树区间更新 & 二进制)
- 区间树(segment tree)
- SPOJ 11840. Sum of Squares with Segment Tree (线段树,区间更新)
- POJ2352 Interval Tree, Segment Tree, 线段树, 区间树
- 线段树(segment tree)
- 线段树(Segment Tree)
- 线段树(segment tree)
- segment tree(线段树)
- Segment Tree(线段树)
- 线段树(segment tree)
- 线段树(segment tree)
- 线段树(segment tree)
- 线段树(segment tree)
- 线段树(segment tree)
- 图像连通域检测的2路算法Code
- 高速公路沥青路面病害分析及养护
- android studio external tool 自定义工具(Javah命令)
- scanf&printf VS cin&cout
- 第一封博客--记录从技术支持转岗c#开发
- XTU1238:Segment Tree(线段树区间更新)
- [cocos2dx笔记016]cocos2dx 3.2 的UserDefault
- php将字符首字母大小写转换
- 曾经经历的面试题汇总(2)
- Linux iconv --字符编码转换工具
- json
- 内核同步机制
- Linux ldd -- 查看可执行文件所依赖的动态链接库
- NSString 和NSData 转换