线段树三:求任意区间的最值

从做这几个题目我发现了,能调用库函数的尽量调用库函数,不然的话可能会超时。不信可以试,在题1的头文件下定义宏:

#define min(a,b) (a)<(b)?(a):(b)

在题2中定义宏:

#define max(a,b) (a)>(b)?(a):(b)

题1:Tyvj 1038(忠诚),给定区间求最小值。只需更改Query即可,由于没有修改操作,可以删除Update操作。

#include<iostream>
#include<cstring>
#include<cstdio> 
#include<cmath> 
using namespace std;
const int MAX=100010;
const int Inf=100000000;
//#define min(a,b) (a)<(b)?(a):(b) 不要加这个,加后会超时 
#define Lson L,mid,root<<1
#define Rson mid+1,R,root<<1|1
int n,m,Min[MAX<<2];
int Pushup(int root) 
{   Min[root]=min(Min[root<<1],Min[root<<1|1]);
}
void Build(int L,int R,int root)
{   if(L==R) 
    {   scanf("%d",&Min[root]);
        return ;
    }
    int mid=(L+R)>>1;
    Build(Lson); 
    Build(Rson); 
    Pushup(root); 
}
int Query(int ql,int qr,int L,int R,int root) 
{   if(ql<=L && R<=qr) return Min[root];
    int mid=(L+R)>>1;
    int res=Inf;
    if(ql<=mid) res=min(res,Query(ql,qr,Lson));
    if(qr>mid) res=min(res,Query(ql,qr,Rson));
    return res;
}
int main()
{   int a,b;
    scanf("%d%d",&n,&m);
    Build(1,n,1);
    for(int i=0;i<m;i++)   
    {   scanf("%d%d",&a,&b);
        printf("%d\n",Query(a,b,1,n,1));
    } 
    return 0;
}

例题2:HDU 1754(I hate it),给定区间求最大值,记得update中只是更新该结点的值。

#include<iostream>
#include<cstring>
#include<cstdio> 
#include<cmath> 
using namespace std;
const int MAX=200010;
//#define max(a,b) (a)>(b)?(a):(b) 不要加这个,加后会超时 
#define Lson L,mid,root<<1
#define Rson mid+1,R,root<<1|1
int n,m,Max[MAX<<2];
int Pushup(int root) 
{   Max[root]=max(Max[root<<1],Max[root<<1|1]);
}
void Build(int L,int R,int root)
{   if(L==R) 
    {   scanf("%d",&Max[root]);
        return ;
    }
    int mid=(L+R)>>1;
    Build(Lson); 
    Build(Rson); 
    Pushup(root); 
}
void Update(int q,int val,int L,int R,int root)
{   if(L==R)
    {   Max[root]=val;
        return ;
    } 
    int mid=(L+R)>>1;
    if(q<=mid) Update(q,val,Lson);
    else Update(q,val,Rson); 
    Pushup(root);
}
int Query(int ql,int qr,int L,int R,int root) 
{   if(ql<=L && R<=qr) return Max[root];
    int mid=(L+R)>>1;
    int res=0;
    if(ql<=mid) res=max(res,Query(ql,qr,Lson));
    if(qr>mid) res=max(res,Query(ql,qr,Rson));
    return res;
}
int main()
{   int a,b;
    while(~scanf("%d%d",&n,&m))
    {   Build(1,n,1);   
        char op[5];
        getchar();
        while(m--)
        {   scanf("%s%d%d",op,&a,&b);
            if(op[0]=='U') Update(a,b,1,n,1);
            if(op[0]=='Q') printf("%d\n",Query(a,b,1,n,1));
        }
    } 
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值