zoukankan      html  css  js  c++  java
  • 线段树——区间合并 单点更新 模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3308

    #include<algorithm>
    #include<cstring>
    #include<cstdio> 
    #include<iostream>
    using namespace std;
    struct node{
        int ls,rs,ms;   //ls 区间左连续序列的长度 
    };
    node no[8*100000];
    int a[8*100000];
    void pushup(int cr,int l,int r){
        no[cr].ls=no[cr<<1].ls;       
        no[cr].rs=no[cr<<1|1].rs;
        no[cr].ms=max(no[cr<<1|1].ms,no[cr<<1].ms);;
    
        int mid=(l+r)/2;    
        if( no[cr].ls==mid-l+1 && a[mid]<a[mid+1]  ){ //区间左连续与 右子区间左连续 
            no[cr].ls+=no[cr<<1|1].ls; 
        }     
        if( no[cr].rs==r-mid && a[mid]<a[mid+1] ){  //区间右连续与 左子区间右连续 
            no[cr].rs+=no[cr<<1].rs; 
        }
        if(a[mid]<a[mid+1])
        no[cr].ms=max(no[cr].ms,no[cr<<1].rs+no[cr<<1|1].ls);
    }
    
    void build(int l,int r,int cr){
        if(l==r){
            no[cr].ls=no[cr].rs=no[cr].ms=1;
            return ;
        }
        int mid=(l+r)/2;
        build(l,mid,cr<<1);
        build(mid+1,r,cr<<1|1);
        pushup(cr,l,r);    
    }
    
    int query(int l,int r,int cr,int L,int R){
        if(l==L&&r==R){    
            return no[cr].ms;
        }
        int mid=(L+R)/2,ans=0;
        if( r<=mid ){                          //左边找 
            ans=query(l,r,cr<<1,L,mid);    
        }  
        else if(l>mid){                            //或右边找 
            ans=query(l,r,cr<<1|1,mid+1,R);
        }
        else {                //中间找 
    		ans=max(query(l,mid,cr<<1,L,mid),query(mid+1,r,cr<<1|1,mid+1,R)); //左边最长,右边最长 
    		if(a[mid]<a[mid+1])
    			ans=max( min( no[cr<<1].rs, mid-l+1 )+min( no[cr<<1|1].ls,r-mid),ans); //中间最长 
        }
        return ans;                    
    }
    void update(int p,int val,int L,int R,int cr){
        if(L==p&&R==p){
            a[p]=val;
            return ;
        }
        int mid=(L+R)/2;
        if(p<=mid) update(p,val,L,mid,cr<<1);
        else update(p,val,mid+1,R,cr<<1|1); 
        pushup(cr,L,R);
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            int n,m;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            build(1,n,1);
            getchar();
            while(m--){
                char s[5];
                scanf("%s",s);
                if(s[0]=='U'){
                    int b,c;
                    scanf("%d%d",&b,&c);
                       update(b+1,c,1,n,1);
                }else {
                    int b,c;
                    scanf("%d%d",&b,&c);
                    b++,c++;
                    printf("%d
    ",query(b,c,1,1,n));
                }
           }
    
        }
    } 
    

      

  • 相关阅读:
    MySQL——事务,索引
    Python——多线程
    Python输入输出
    MySQL与Python的交互——增删改
    MySQL与Python的交互————查询
    Python的学习路
    MySQL数据库
    MySQL条件查询
    设计模式笔记 抽象工厂模式
    设计模式笔记 建造者模式
  • 原文地址:https://www.cnblogs.com/z-bear/p/9438150.html
Copyright © 2011-2022 走看看