• hdu3308


    hdu3308 LCIS
    传送门
    题意
    给出一个(n(1leq nleq 100000))个数的序列,进行(m(1leq mleq 100000))次操作,每次操作修改一个数的值或者计算一段连续区间内最长递增子串的长度
    题解
    线段树区间合并
    每个节点维护三个变量:区间内最长递增子串的长度,从区间左端点开始的最长递增子串的长度,从区间右端点开始的最长递增子串的长度
    (pushup)函数中对三个变量分别进行修改
    最终结果会在左区间,右区间,跨越左右区间三者之一处取到

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<set>
    #include<map>
    #include<cstring>
    #include<string>
    #include<sstream>
    #include<cmath>
    #include<ctime>
    #include<algorithm>
    #define LL long long
    #define PII pair<int,int>
    #define PLL pair<LL,LL>
    #define pi acos(-1.0)
    #define eps 1e-6
    #define lowbit(x) x&(-x)
    using namespace std;
    
    const int maxn=100010;
    int T,n,m,a[maxn];
    char s[5];
    struct node{
        int amx,lmx,rmx;
    }tree[4*maxn];
    
    void pushup(int o,int l,int r){
        int mid=(l+r)>>1;
        tree[o].amx=max(tree[o<<1].amx,tree[o<<1|1].amx);
        if(a[mid]<a[mid+1]) tree[o].amx=max(tree[o].amx,tree[o<<1].rmx+tree[o<<1|1].lmx);
        tree[o].lmx=tree[o<<1].lmx;
        if(tree[o].lmx==mid-l+1 && a[mid]<a[mid+1]) tree[o].lmx+=tree[o<<1|1].lmx;
        tree[o].rmx=tree[o<<1|1].rmx;
        if(tree[o].rmx==r-mid && a[mid]<a[mid+1]) tree[o].rmx+=tree[o<<1].rmx;
    }
    
    void build(int o,int l,int r){
        if(l==r){
            tree[o].amx=tree[o].lmx=tree[o].rmx=1;
            return;
        }
        int mid=(l+r)>>1;
        build(o<<1,l,mid);
        build(o<<1|1,mid+1,r);
        pushup(o,l,r);
    }
    
    void change(int o,int l,int r,int x,int v){
        if(l==r){
            a[l]=v;
            return;  
        }
        int mid=(l+r)>>1;
        if(x<=mid) change(o<<1,l,mid,x,v);
        else change(o<<1|1,mid+1,r,x,v);
        pushup(o,l,r);
    }
    
    int query(int o,int l,int r,int ql,int qr){
        if(ql<=l && r<=qr) return tree[o].amx;
        int mid=(l+r)>>1;
        int ans=0;
        //左区间最值
        if(ql<=mid) ans=max(ans,query(o<<1,l,mid,ql,qr));
        //右区间最值
        if(qr>mid) ans=max(ans,query(o<<1|1,mid+1,r,ql,qr));
        //跨越左右区间的最值
        if(ql<=mid && qr>mid && a[mid]<a[mid+1]){
            ans=max(ans,min(mid-ql+1,tree[o<<1].rmx)+min(qr-mid,tree[o<<1|1].lmx));
        }
        return ans;
    }
    
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%d %d",&n,&m);
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            build(1,1,n);
            while(m--){
                scanf("%s",s);
                if(s[0]=='U'){
                    int x,y;
                    scanf("%d %d",&x,&y);
                    x++;
                    change(1,1,n,x,y);
                }
                else{
                    int l,r;
                    scanf("%d %d",&l,&r);
                    l++;
                    r++;
                    printf("%d
    ",query(1,1,n,l,r));
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Java 基础巩固:装箱拆箱 你真的熟悉吗
    Java数据类型的转换:隐式(自动)转换与强制转换
    oozie学习笔记
    flume学习笔记
    sqoop学习笔记
    Oracle故障排查之oracle解决锁表问题
    zookerper安装部署
    hadoop HA架构安装部署(QJM HA)
    hadoop第一部分-安装、测试
    hadoop完全分布式安装部署-笔记
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13546075.html
Copyright © 2020-2023  润新知