nyoj 1185 最大最小值 【线段树】
2015-11-16 11:59
351 查看
最大最小值
时间限制:1000 ms | 内存限制:65535 KB难度:2
描述
给出N个整数,执行M次询问。
对于每次询问,首先输入三个整数C、L、R:
如果C等于1,输出第L个数到第R个数之间的最小值;
如果C等于2,输出第L个数到第R个数之间的最大值;
如果C等于3,输出第L个数到第R个数之间的最小值与最大值的和。
(包括第L个数和第R个数)。
输入首先输入一个整数T(T≤100),表示有T组数据。
对于每组数据,先输入一个整数N(1≤N≤10000),表示有N个整数;
接下来一行有N个整数a(1≤a≤10000);
然后输入一个整数M,表示有M次询问;
接下来有M行(1≤M≤10000),每行有3个整数C、L、R(1≤C≤3,1≤L≤R≤N)。
输出按照题意描述输出。每个输出占一行。
样例输入
2 4 1 3 2 4 2 1 1 4 2 2 3 5 1 2 3 4 5 1 3 1 5
样例输出
1 3 6
来源原创
上传者
TC_李远航
思路:
求最大值就需要建立最大树,求最小值就需要建立最小数,然后建立之后就只需要进行查找了,建立的时候可以同时建立两个树,但是当你查找的时候因为你的需要不同,所以你就需要写两个实现不同功能的函数,一个是实现求最大值的函数,也就是在最大树中找最大值,在最小树中找最小值,就OK了!
代码如下:
方法一:
#include <stdio.h> #include <string.h> #include <algorithm> #define INF 0x3f3f3f3f using namespace std; int n,m; int tree1[40005]; int tree2[40005]; int c,l,r; int min(int a,int b) { if(a>b) return b; return a; } int max(int a,int b) { if(a>b) return a; return b; } void build(int rt,int l,int r) { if(l==r) { scanf("%d",&tree1[rt]); tree2[rt]=tree1[rt]; return; } int mid=(l+r)>>1,pt=rt<<1; build(pt,l,mid); build(pt|1,mid+1,r); tree1[rt]=min(tree1[pt],tree1[pt|1]); tree2[rt]=max(tree2[pt],tree2[pt|1]); } int find1(int rt,int l,int r,int a,int b) { if(l>=a&&r<=b) { return tree1[rt]; } int mid=(l+r)>>1,pt=rt<<1,res=INF; if(a<=mid) { res=min(find1(pt,l,mid,a,b),res); } if(b>mid) { res=min(find1(pt|1,mid+1,r,a,b),res); } return res; } int find2(int rt,int l,int r,int a,int b) { if(l>=a&&r<=b) { return tree2[rt]; } int mid=(l+r)>>1,pt=rt<<1,res=-1; if(a<=mid) { res=max(find2(pt,l,mid,a,b),res);//在它的左子树中找最小值 }//对应的数组的下标也是他的下标的2倍,pt代表的就是l到mid中的最小值 //如果满足l到mid在a,b的范围内说明找到最小值了,直接返回,将所有的a,b范围内的 //最小值都找到之后进行比较,输出最小的值! if(b>mid)//这个是在右子树中找最小值 {//pt|1代表的是mid+1到r中的最小值,如果不在a,b区间里面,就继续递归,如果在a,b区间里面就直接返回最大值 res=max(find2(pt|1,mid+1,r,a,b),res); } return res; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); build(1,1,n); scanf("%d",&m); while(m--) { scanf("%d%d%d",&c,&l,&r); if(c==1) { printf("%d\n",find1(1,1,n,l,r)); } else if(c==2) { printf("%d\n",find2(1,1,n,l,r)); } else if(c==3) { printf("%d\n",find1(1,1,n,l,r)+find2(1,1,n,l,r)); } } } return 0; }
方法二:
#include <stdio.h> #include <string.h> #include <algorithm> #define INF 0x3f3f3f3f using namespace std; int n,m; int tree1[40005]; int tree2[40005]; int c,l,r; int min(int a,int b) { if(a>b) return b; return a; } int max(int a,int b) { if(a>b) return a; return b; } void build(int rt,int l,int r) { if(l==r) { scanf("%d",&tree1[rt]); tree2[rt]=tree1[rt]; return; } int mid=(l+r)>>1,pt=rt<<1; build(pt,l,mid); build(pt|1,mid+1,r); tree1[rt]=min(tree1[pt],tree1[pt|1]); tree2[rt]=max(tree2[pt],tree2[pt|1]); } int find1(int rt,int l,int r,int a,int b) {//这个方法是要么在左子树里面查找,要么在右子树中查找,要么在左右子树中查找 //其实是一样的! if(l>=a&&r<=b) { return tree1[rt]; } int mid=(l+r)>>1,pt=rt<<1,res=INF; if(b<=mid) { res=min(find1(pt,l,mid,a,b),res); } else if(a>mid) { res=min(find1(pt|1,mid+1,r,a,b),res); } else { res=min(find1(pt,l,mid,a,b),res); res=min(find1(pt|1,mid+1,r,a,b),res); } return res; } int find2(int rt,int l,int r,int a,int b) { if(l>=a&&r<=b) { return tree2[rt]; } int mid=(l+r)>>1,pt=rt<<1,res=-1; if(b<=mid) { res=max(find2(pt,l,mid,a,b),res); } else if(a>mid) { res=max(find2(pt|1,mid+1,r,a,b),res); } else { res=max(find2(pt,l,mid,a,b),res); res=max(find2(pt|1,mid+1,r,a,b),res); } return res; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); build(1,1,n); scanf("%d",&m); while(m--) { scanf("%d%d%d",&c,&l,&r); if(c==1) { printf("%d\n",find1(1,1,n,l,r)); } else if(c==2) { printf("%d\n",find2(1,1,n,l,r)); } else { printf("%d\n",find1(1,1,n,l,r)+find2(1,1,n,l,r)); } } } return 0; }
相关文章推荐
- dom4j 解析xml字符串 去除.DTD校验
- Codeforces Gym 100796E Permutation Polygon(线段树)
- xdubbo: 将 spring 管理的 bean 暴露为 http 服务
- Ubuntu 12.04搭建Andorid编译环境
- selenium之ExpectedConditions类
- jsp编程获取当前目录下的文件和目录及windows盘符的方法
- Win10 TH2正式版升级时停电中断怎么继续升级?
- 极客头条贡献者招募:欢迎懂分享的人
- Webservices笔记
- JS登录验证
- 跟我学习javascript的call(),apply(),bind()与回调
- 15-11-16 Eclipse 操作菜单汉译之Edit [编辑]
- 解决eclipse的 验证位置时发生错误 方法
- UML图之类图,对象图和包图
- 结构体对象与对象间的赋值到底复制了什么
- 解决iOS9网络请求失败问题
- java POI 将txt文件导入到excel中
- 【悟】终于入手PS4
- 离散系统的差分方程、冲激响应和卷积分析
- maven compile的web项目时指定/WEB-INF/lib 目录作为额外的库目录