求最大值(经典线段树)
来源:互联网 发布:性格测试软件 编辑:程序博客网 时间:2024/06/05 15:12
题目链接:https://www.nowcoder.com/acm/contest/30/E
时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
给出一个序列,你的任务是求每次操作之后序列中 (a[j]-a[i])/(j-i)【1<=i < j<=n】 的最大值。
操作次数有Q次,每次操作需要将位子p处的数字变成y.
输入描述:
本题包含多组输入,每组输入第一行一个数字n,表示序列的长度。
然后接下来一行输入n个数,表示原先序列的样子。
再接下来一行一个数字Q,表示需要进行的操作的次数。
最后Q行每行两个元素p,y,表示本操作需要将位子p处的数字变成y.
数据范围:
3<=n<=200000
1<=Q<=200000
-1000000000<=a[i]<=1000000000
输出描述:
每组数据输出Q行,每行输出一个浮点数,保留两位小数,表示所求的最大值。
示例1
输入
5
2 4 6 8 10
2
2 5
4 9
输出
3.00
3.00
说明
第一次操作之后的序列变成:2 5 6 8 10
第二次操作之后的序列变成:2 5 6 9 10
备注:
输入只有整形
思路:(a[j]-a[i])/(j-i)这是斜率,所以最大值只会出现在相邻的两个数中。
用线段树,用数组(数组b)记录相邻两个数的差值,这样就转化为了,查找b数组中的最大值,只要不断更新即可(线段树+点更新+询问最值问题),这一题最主要的就是转化为线段树问题。
代码:
#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;const int N=200009;struct node{ int s,e; double p;} dis[N*4+10];double a[N];int map1[N];void build(int num,int s,int e)//建树{ dis[num].s=s; dis[num].e=e; if(s==e) { dis[num].p=a[s]; return ; } int mid=(s+e)/2; build(num<<1,s,mid); build(num<<1|1,mid+1,e); dis[num].p=max(dis[num<<1].p,dis[num<<1|1].p);//记录最大值}void update(int num,int k,double pp)//更新点的权值{ dis[num].p=-2000000009;//这里一定要赋成最小的值。 if(dis[num].s==dis[num].e) { if(dis[num].s==k) dis[num].p=pp; return ; } int mid=(dis[num].s+dis[num].e)/2; if(mid<k) update(num<<1|1,k,pp); else update(num<<1,k,pp); dis[num].p=max(dis[num].p,max(dis[num<<1].p,dis[num<<1|1].p));}int main(){ int n; while(~scanf("%d",&n)) { memset(map1,0,sizeof(map1)); memset(a,0,sizeof(a)); memset(dis,0,sizeof(dis)); int k=0; scanf("%d",&map1[1]); for(int i=2; i<=n; i++) { scanf("%d",&map1[i]);//map1记录数组的值 a[++k]=map1[i]*1.000-map1[i-1]*1.000;//a记录相邻两点的差值 } build(1,1,k);//建树 int m; scanf("%d",&m); for(int i=0; i<m; i++) { int pi,v; scanf("%d%d",&pi,&v); map1[pi]=v; if(pi<n)//更新 { a[pi]=map1[pi+1]*1.000-map1[pi]*1.000; update(1,pi,a[pi]); } if(pi>1) { a[pi-1]=map1[pi]*1.000-map1[pi-1]*1.000; update(1,pi-1,a[pi-1]); } printf("%.2lf\n",dis[1].p); } } return 0;}
阅读全文
0 0
- 求最大值(经典线段树)
- hdu1754-线段树(求区间最大值)
- 线段树求区间最大值
- 线段树区间求最大值
- 线段树求区间最大值
- 线段树求区间最大值和最小值(指针)
- hdu1754--I Hate It(线段树求最大值)
- 线段树(单点更新,区间求最大值)
- 卿学姐与公主(线段树区间求最大值)
- 1754 I Hate It(线段树求区间最大值)
- HDU1823 二维线段树 求最大值
- poj3264 线段树求最大值,最小值
- hdu2795-Billboard (线段树求区间最大值)
- 【线段树】最大值(单点)
- 求区间内最大值问题(线段树)(hdu 1754)
- hdu 1754 I Hate It (线段树--求区间最大值)(基础)
- HDU 1754 I Hate It(线段树--单点赋值, 区间求最大值)
- 【hdu】I Hate It(线段树,结点修改求区间最大值)
- 解决FileDownloader库中无全部开始下载任务接口的问题
- 5.2 二叉树的链式存储实验
- 利用邻接表进行拓扑排序
- 0pe单文件夹,grub菜单全外置版
- bzoj2809 [Apio2012]dispatching(可并堆)
- 求最大值(经典线段树)
- 大纲
- 初学者---Android 学习资料
- 51nod 0和1相等串
- Ciclop开源3D扫描仪软件---Horus源码分析之src\horus\engine\calibration\platform_extrinsics.py
- Java抽象(方法,类)和Java的接口
- springboot---helloworld
- 将virtio集成slipstream到windows iso,winpe – 原生方法和利用0pe
- history.go(-1)和history.back()的区别和联系