[复习]线段树 系列操作I
2017-09-22 19:32
134 查看
题目背景
Problem A:系列操作Ⅰ
题目描述
给出序列 a1,a2,…,an (0≤ai≤109) ,有关于序列的两种操作:
ai (1≤i≤n) 加上x(-103≤x≤103)
求 max{al,al+1,…,ar} (1≤l≤r≤n)
输入格式
第一行包含两个数 n(1≤n≤105)和 m(1≤m≤105),表示序列长度和操作次数。
接下来一行n个数,以空格隔开,表示 a1,a2,…,an。
接下来 m 行,每行为以下两种格式之一。
0 i x ,表示 ai 加上 x 。
1 l r ,求 max{ al,al+1,…,ar }。
输出格式
对于每次询问,输出单独的一行表示答案。
样例数据
输入
5 3
1 2 3 4 5
1 1 5
0 5 -5
1 1 5
输出
5
4
分析:线段树模板
代码
本题结。
Problem A:系列操作Ⅰ
题目描述
给出序列 a1,a2,…,an (0≤ai≤109) ,有关于序列的两种操作:
ai (1≤i≤n) 加上x(-103≤x≤103)
求 max{al,al+1,…,ar} (1≤l≤r≤n)
输入格式
第一行包含两个数 n(1≤n≤105)和 m(1≤m≤105),表示序列长度和操作次数。
接下来一行n个数,以空格隔开,表示 a1,a2,…,an。
接下来 m 行,每行为以下两种格式之一。
0 i x ,表示 ai 加上 x 。
1 l r ,求 max{ al,al+1,…,ar }。
输出格式
对于每次询问,输出单独的一行表示答案。
样例数据
输入
5 3
1 2 3 4 5
1 1 5
0 5 -5
1 1 5
输出
5
4
分析:线段树模板
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<ctime> #include<cmath> #include<algorithm> #include<cctype> #include<iomanip> #include<queue> #include<set> using namespace std; int getint() { int f=1,sum=0; char ch; for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar()); if(ch=='-') { f=-1; ch=getchar(); } for(;ch>='0'&&ch<='9';ch=getchar()) sum=(sum<<3)+(sum<<1)+ch-48; return sum*f; } const int INF=0x3f3f3f3f; const int maxn=100010; long long a[maxn],treemax[4*maxn]; int n,m; void buildtree(int num,int l,int r) { if(l==r) { treemax[num]=a[l];//l和r都是a数组的标号,num才是treemax的 return; } int mid=l+r>>1; buildtree(num<<1,l,mid); buildtree(num<<1|1,mid+1,r);//mid记得+1 treemax[num]=max(treemax[num<<1],treemax[num<<1|1]); } void change(int num,int l,int r,int findnum,int x) { if(l==r) { treemax[num]+=x; return; } int mid=l+r>>1; if(mid>=findnum)//注意等号 change(num<<1,l,mid,findnum,x); else change(num<<1|1,mid+1,r,findnum,x);//注意+1和等号的位置 treemax[num]=max(treemax[num<<1],treemax[num<<1|1]);//记得更新数组 } long long check(int num,int l,int r,int ll,int rr) { if(ll<=l&&rr>=r) return treemax[num]; int mid=l+r>>1,a=-INF,b=-INF;//注意a、b赋值 if(ll<=mid) a=check(num<<1,l,mid,ll,rr); if(rr>mid) b=check(num<<1|1,mid+1,r,ll,rr); return max(a,b); } int main() { freopen("xlcz.in","r",stdin); freopen("xlcz.out","w",stdout); n=getint();m=getint(); for(int i=1;i<=n;++i) a[i]=getint(); buildtree(1,1,n); int bj,x,y; long long ans; while(m--) { bj=getint();x=getint();y=getint(); if(bj==0) change(1,1,n,x,y); else { ans=check(1,1,n,x,y); cout<<ans<<'\n'; } } return 0; }
本题结。
相关文章推荐
- Java基础复习笔记系列 七 IO操作
- bzoj 1858: [Scoi2010]序列操作(线段树)
- java 操作格子问题(线段树)
- linux C复习:文件操作(创建、打开、读写)
- hdu3397 Sequence operation 线段树区间更新&&bzoj1858: [Scoi2010]序列操作
- php基础系列:从用户登录处理程序学习mysql扩展基本操作
- C# 串口操作系列(4) -- 协议篇,文本协议数据解析
- Oracle 数据库系列 - SQL Plus SQL操作命令
- C#操作Excel开发报表系列整理
- 【HDU4288 Coder】离线+离散化+5颗线段树的更新操作
- 云星数据---Scala实战系列(精品版)】:Scala入门教程047-Scala实战源码-Scala method操作
- elk系列4之kibana图形化操作
- Struts2基础复习系列(1)
- Java基础复习笔记系列之 常用类
- B树系列文章(2)--插入操作
- C# 串口操作系列(1) -- 入门篇,一个标准的,简陋的串口例子。
- Just a Hook ---- 线段树成段更新(LAZY 操作)
- 【转载】实战操作主机角色转移,Active Directory系列之十
- 【POJ 3321】【dfs序(讲解)+(树状数组或者线段树)】Apple Tree【给你一颗树,最初每个节点上都有一个苹果,有两种操作单点修改和查询子树的苹果个数】
- 计算机图形学-实验5-掌握Bezier样条曲面生成思想、复习基本图元绘制、交互操作和几何变换相关内容