• hdu1754线段树入门


    题意:给出N个数,然后M个操作,操作又Q和U2种,Q A B 代表 询问A-B之间的最大值,U A B 代表把A的值更新为B
    分析:简单的线段树,属于模板题

    线段树,一种二叉搜索树,每个节点代表一段区间。在该结构上的操作在log级别。

    结构什么的还是自己看代码吧,有个整体概念后,根据题来看懂代码这种能力还是很必要。

    今天刚接触的树,还是参照别人的代码ac的。感觉线段树用处会更多,需要在这个方面深学。

    代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    struct segtree  
    {  
        int l;  
        int r;  
        int mid;  
        int max;  
    }T[600011];  
      
      
    int max(int a,int b)  
    {  
        return a>b?a:b;  
    }  
      
      
    void construct(int l,int r,int k)  //二叉树
    {     
        T[k].l=l;  
        T[k].r=r;  
        T[k].mid=(l+r)/2;  
        T[k].max=-1;  
      
      
        if(l==r)    return ;  
          
        construct(l,T[k].mid,2*k);  
        construct(T[k].mid+1,r,2*k+1);  
    }  
      
      
    void insert(int n,int d,int k)  
    {  
        if(T[k].l==T[k].r&&T[k].l==d)   {T[k].max=n;return ;}   //元线段处理 
      
                                                            //查找该插入的位置
        if(d<=T[k].mid)  insert(n,d,2*k);  
        else            insert(n,d,2*k+1);  
        T[k].max=max(T[2*k].max,T[2*k+1].max);             //给该线段节点更新max
    }  
      
      
    int ans;  
    void search(int l,int r,int k)              //类似深搜
    {  
        if(T[k].l==l&&T[k].r==r)    {ans=max(ans,T[k].max);return ;}  
      
      
        if(r<=T[k].mid)      search(l,r,2*k);  
        else if(l>T[k].mid)  search(l,r,2*k+1);  
        else  
        {  
            search(l,T[k].mid,2*k);  
            search(T[k].mid+1,r,2*k+1);  
        }  
    }  
      
      
    int main()  
    {  
        int n,m;  
        int temp;  
        int i;  
      
      
        char c[3];  
        int a,b,t;  
      
      
        while(scanf("%d%d",&n,&m)!=-1)  
        {  
            construct(1,n,1);  //建树  对象为学生线段
      
      
            for(i=1;i<=n;i++)     
            {  
                scanf("%d",&temp);          
                insert(temp,i,1);               //将temp插入并更新树
            }  
      
      
            for(i=0;i<m;i++)  
            {  
                scanf("%s%d%d",c,&a,&b);  
                if(c[0]=='U')   insert(b,a,1);      //重新插入
                else  
                {  
                    if(a>b)  {t=a;a=b;b=t;}           
                    ans=0;  
                    search(a,b,1);                   
                    printf("%d\n",ans);  
                }  
            }  
        }  
        return 0;  
    }  
    


     

  • 相关阅读:
    2019/09/26,经济和科技
    失败的总和
    2019/11/05,现代人的焦虑
    2019/09/16,回忆和希望
    2019/09/13,捷径
    演讲手势
    因果谬论和基于数据的另一种说法
    文本框输入事件:onchange 、onblur 、onkeyup 、oninput
    开关按钮切换
    全选,反选,全不选
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134192.html
Copyright © 2020-2023  润新知