HDU 1754 I Hate It .

本文详细解析了线段树算法的基本概念、实现细节及优化策略,并通过实例展示了其在解决区间查询问题时的应用场景。重点讨论了宏定义在函数调用中的注意事项,以及如何避免重复计算以提高程序效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很水很水的线段树,然后犯了一个很弱的错误,宏定义搞函数的时候,各种小心要~

 

/*
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define NN 200010
#define get_max(a,b) (a>b?a:b)
struct node{
	int l,r,val;
}seg_tree[NN*4];
int C[NN],seg_len;
void Init(int t,int l, int r)
{
	int mid = ( l + r)>>1;
	seg_tree[t].l = l;
	seg_tree[t].r = r;
	if(r-l == 1){
		seg_tree[t].val = C[l];
		return ;
	}
	seg_len = seg_len < t ? t:seg_len;
	Init(t<<1,l,mid);
	Init(t<<1|1,mid,r);
	seg_tree[t].val = get_max(seg_tree[t<<1].val,seg_tree[t<<1|1].val);
	//if(seg_tree[t<<1].val < seg_tree[t<<1|1].val)
	//	seg_tree[t].val = seg_tree[t<<1|1].val;
	//	else seg_tree[t].val = seg_tree[t<<1].val;
}
void insert(int t,int l, int r ,int val){
	int mid = (seg_tree[t].l+seg_tree[t].r)>>1;
	if(seg_tree[t].l == l && seg_tree[t].r == r){
		seg_tree[t].val = val;
		return ;
	}
	if(t > seg_len )return;
	if(l >= mid)insert(t<<1|1,l,r,val);
	else if(r <= mid)insert(t<<1,l,r,val);
	else {
		insert(t<<1,l,mid,val);
		insert(t<<1|1,mid,r,val);
	}
	//if(seg_tree[t<<1].val < seg_tree[t<<1|1].val)
	//	seg_tree[t].val = seg_tree[t<<1|1].val;
	//else seg_tree[t].val = seg_tree[t<<1].val;
	seg_tree[t].val = get_max(seg_tree[t<<1].val,seg_tree[t<<1|1].val);
}
int Search(int t,int l, int r){
	int max,max1,mid = (seg_tree[t].l+seg_tree[t].r)>>1;
	if(seg_tree[t].l >= l && seg_tree[t].r <= r)
		return seg_tree[t].val ;
	//if(t > seg_len) return 0;
	if( l >= mid) return Search(t<<1|1,l,r);
	else if( r <= mid)return  Search(t<<1,l,r);
	else{
		max1 = Search(t<<1,l,mid);
		max = Search(t<<1|1,mid,r);
		if(max < max1)max = max1;
		return  max;
	//	return get_max(Search(t<<1,l,mid),Search(t<<1|1,mid,r));
		//无脑的一个地方,宏定义调用的话,相当于多求了一遍,所费时间对整个
		//程序来说,囧rz~
	}
}
int main()
{
	int i,x,y,n,m;
	char s[2];
	//printf("%d\n",Max);
	while(scanf("%d%d",&n,&m)!=EOF){
		seg_len = 0;
		for(i=0;i<n;i++)scanf("%d",&C[i]);
		Init(1,0,n+1);
		while(m--){
			scanf("%s %d %d",s,&x,&y);
			if(s[0] == 'U'){
				insert(1,x-1,x,y);
			}
			else printf("%d\n",Search(1,x-1,y));
		}
		for(i=0;i<=seg_len;i++)seg_tree[i].l=seg_tree[i].r=seg_tree[i].val =0;
	}
	return 0;
}*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define NN 200000
#define Max(a,b) (a>b?a:b)
int len_seg;
struct node{
    int r,l,val;
}seg_tree[NN*4];
void Init(int t,int l,int r){
    int mid = (l+r)>>1;
    seg_tree[t].val = 0;
    seg_tree[t].l = l;
    seg_tree[t].r = r;
    len_seg = len_seg<t?t:len_seg;
    if(r==l )return ;
    Init(t*2,l,mid);
    Init(t*2+1,mid+1,r);

}
void insert(int t,int val,int tmp)
{
    int l = seg_tree[t].l;
    int r = seg_tree[t].r;
    int mid = (l+r)>>1;
    if(r==l && l==tmp){
        seg_tree[t].val = val;
        return ;
    }
    if(t>len_seg)return ;
    if(tmp>=l && tmp <=r && seg_tree[t].val < val)seg_tree[t].val = val;
    if(tmp<=mid)
        insert(t*2,val,tmp);
    else insert(t*2+1,val,tmp);
    seg_tree[t].val = Max(seg_tree[t*2].val , seg_tree[t*2+1].val);
}
int Search(int t,int a,int b){
    int max,max1,mid = (seg_tree[t].l+seg_tree[t].r)>>1;
    if(t > len_seg)return 0;
    if( seg_tree[t].l == a && seg_tree[t].r == b)
        return seg_tree[t].val;
    if(b<=mid)return Search(t*2,a,b);
    else if(a>mid) return Search(t*2+1,a,b);
    else {
       max=Search(t*2,a,mid);
	   max1=Search(t*2+1,mid+1,b);
	   if(max1>max)max=max1;
	   return max;
    }
}
int main()
{
    int n,m,i,a,b;
    char ch[2];
    while(~scanf("%d%d",&n,&m)){
        len_seg = 0;
        Init(1,1,200000);
        for(i=1;i<=n;i++){
            scanf("%d",&a);
            insert(1,a,i);
        }
        while(m--){
            scanf("%s %d %d",ch,&a,&b);
            if(ch[0] == 'Q'){
                printf("%d\n",Search(1,a,b));
            }
            else insert(1,b,a);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值