nyoj--1185

最大最小值

时间限制: 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
 
   
解题思路:这是我的第三道线段树.建树时增加最大项,最小项,就行了.当c==3时,只需让调用函数时找到的最大值加上调用函数找到的最小值就行了,其它和模板没太大区别.
 
   
代码如以下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct stu
{
	//int l,r,minn,maxn,sum;
	int l,r,minn,maxn;
};
stu node[100000];
int num[10000+10];
void  build(int i,int l,int r)
{
	int mid;
	node[i].l=l;
	node[i].r=r;
	if(l==r)
	{
		node[i].minn=num[l];
		node[i].maxn=num[l];
		//node[i].sum=num[l];
		return;
	}
	mid=(l+r)/2;
	int a,b,c,d;
	build(2*i,l,mid);
	a=node[2*i].minn;
	c=node[2*i].maxn;
	build(2*i+1,mid+1,r);
	b=node[2*i+1].minn;
	d=node[2*i+1].maxn;
	node[i].minn=min(a,b);
	node[i].maxn=max(c,d);
	//node[i].sum=node[i].maxn+node[i].minn;
}
int big(int i,int s,int e)
{
	int mid;
	if(node[i].l==s&&node[i].r==e)
    return node[i].maxn;
    mid=(node[i].l+node[i].r)/2;
    if(e<=mid)
      return big(2*i,s,e);
      else
      {
      	if(s>mid)
      	return big(2*i+1,s,e);
      	else 
      	return max(big(2*i,s,mid),big(2*i+1,mid+1,e));
      }
}
int small(int i,int s,int e)
{
	int mid;
	if(node[i].l==s&&node[i].r==e)
    return node[i].minn;
    mid=(node[i].l+node[i].r)/2;
    if(e<=mid)
      return small(2*i,s,e);
      else
      {
      	if(s>mid)
      	return small(2*i+1,s,e);
      	else 
      	return min(small(2*i,s,mid),small(2*i+1,mid+1,e));
      }
}
//int all(int i,int s,int e)
//{
//	int mid;
//	if(node[i].l==s&&node[i].r==e)
//    return node[i].sum;
//    mid=(node[i].l+node[i].r)/2;
//    if(e<=mid)
//      return all(2*i,s,e);
//      else
//      {
//      	if(s>mid)
//      	return all(2*i+1,s,e);
//      	else 
//      	return all(2*i,s,mid)+all(2*i+1,mid+1,e);
//      }
//}
int main()
{
    int t,n,m;
    int a,b,c;
   	scanf("%d",&t);
   	while(t--)
   	{
   		scanf("%d",&n);
   		for(int i=1;i<=n;i++)
   		scanf("%d",&num[i]);
   		build(1,1,n);
//   		for(int i=1;i<=2*n;i++)
//   		{
//   			printf("%d %d %d %d %d \n",node[i].l,node[i].r,node[i].minn,node[i].maxn,node[i].sum);
//   		}
		scanf("%d",&m);
	   	for(int i=1;i<=m;i++)
   		{
   			scanf("%d%d%d",&a,&b,&c);
   			if(a==2)
   			{
   				printf("%d\n",big(1,b,c));
   			}
   			else if(a==1)
   			{
   				printf("%d\n",small(1,b,c));
   			}
   			else if(a==3)
   			{
   				printf("%d\n",big(1,b,c)+small(1,b,c));
   			}
   		}
   	}
	return 0;
}

 
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值