• 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;
    }
    
  • 相关阅读:
    再见了亲爱的学生们,再见了敬爱的同事们,再见了信狮
    #if defined 和#ifdef的区别
    C# ASP.NET Core开发学生信息管理系统(二)
    modelsim与debussy联合的问题
    C#批量生成大数据量无重复随机数据的另类高效实现
    DataColumn.Caption属性应用到DataGridView.HeaderText的方法
    [转载]安装网银安全控件
    近期学习SQL Server,收藏的几个学习教程网址备忘
    asp.net根据域名查ip C#版
    asp.net 2.0教程 成员资格和角色管理
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13546075.html
Copyright © 2020-2023  润新知