hdu3308 线段树区间合并

本文详细介绍了如何通过调整UESTC1425代码,成功解决了相关问题的过程。主要内容包括结构体定义、最大值计算、节点更新和查询操作,通过实例展示了算法实现与优化的方法。

同UESTC1425差不多,将代码改了一下过了。。。


ACcode:

#include<stdio.h>
#include<iostream>
using namespace std;

const int size=100000;

struct Node
{
       int li,ri,mi;
       int nl,nr;
       int sum;
}tre[size<<2];

int Max(int a1,int a2)
{
    return a1>a2?a1:a2;   
}

void pushup(int rt)
{
     int r1=rt<<1,r2=r1+1;
     tre[rt].nl=tre[r1].nl;
     tre[rt].nr=tre[r2].nr;
     tre[rt].mi=Max(tre[r1].mi,tre[r2].mi);
     if (tre[r1].nr<tre[r2].nl) 
        tre[rt].mi=Max(tre[rt].mi,tre[r1].ri+tre[r2].li);
     if (tre[r1].li==tre[r1].sum && tre[r1].nr<tre[r2].nl) tre[rt].li=tre[r1].li+tre[r2].li;
     else tre[rt].li=tre[r1].li;
     if (tre[r2].ri==tre[r2].sum && tre[r1].nr<tre[r2].nl) tre[rt].ri=tre[r1].ri+tre[r2].ri;
     else tre[rt].ri=tre[r2].ri;
}

void build(int rt,int l,int r)
{
     tre[rt].sum=r-l+1;
     if (l==r)
     {
        scanf("%d",&tre[rt].nr);
        tre[rt].nl=tre[rt].nr;
        tre[rt].li=tre[rt].ri=tre[rt].mi=1;
        return ;        
     }
     int mid=(l+r)>>1;
     build(rt<<1,l,mid);
     build(rt<<1|1,mid+1,r);
     pushup(rt);
}

void update(int rt,int l,int r,int a,int b)
{
     if (l==r)
     {
        tre[rt].nl=tre[rt].nr=b;
        return ;
     }
     int mid=(l+r)>>1;
     if (a<=mid) update(rt<<1,l,mid,a,b);
     else  update(rt<<1|1,mid+1,r,a,b);
     pushup(rt);
}

Node query(int rt,int l,int r,int L,int R)
{
     if (L<=l&&r<=R) return tre[rt];
     int mid=(l+r)>>1;
     int f1=0,f2=0;
     Node r1,r2,tmp;
     if (L<=mid) { r1=query(rt<<1,l,mid,L,R); f1++; }
     if (R>mid)  { r2=query(rt<<1|1,mid+1,r,L,R); f2++; }
     if (f1&&f2)
     {
        tmp.nl=r1.nl;
        tmp.nr=r2.nr;
        tmp.mi=Max(r1.mi,r2.mi);
        if (r1.nr<r2.nl) tmp.mi=Max(tmp.mi,r1.ri+r2.li);
        if (r1.li==r1.sum && r1.nr<r2.nl) tmp.li=r1.li+r2.li;
        else tmp.li=r1.li;
        if (r2.ri==r2.sum && r1.nr<r2.nl) tmp.ri=r1.ri+r2.ri;
        else tmp.ri=r2.ri;
        return tmp;
     }
     else if (f1) return r1;
     else return r2;
}

int main()
{
    int a,b;
    int i,n,q,T;
    char op[5];
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d %d",&n,&q);
        n--;
        build(1,0,n);    
        while (q--)
        {
              scanf("%s %d %d",op,&a,&b);
              if (op[0]=='Q')
              {      
                 Node tmp=query(1,0,n,a,b);
                 printf("%d\n",tmp.mi);        
              }
              else update(1,0,n,a,b); 
        }
    }
    return 0;   
} 
 				    


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值