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;
}
原文地址:https://www.cnblogs.com/fxq1304/p/13546075.html