HDU LCIS 题解(线段树合并)

题目链接

题目大意

查询区间中最长的连续上升序列,支持单点修改。

题目思路

线段树合并的题目,感觉有点小怪

记录区间中以左边界为起点的答案,和右边界为终点的答案,还有区间总答案

查询的时候也不是普通查询

这个题目记录下

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define fi first
#define se second
#define debug printf("aaaaaaaaaaa\n");
const int maxn=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
const ll INF=0x3f3f3f3f3f3f3f3f;
int n,m;
int a[maxn];
int mal[maxn],mar[maxn],ma[maxn];
void pushup(int node,int l,int r){
    mal[node]=mal[node<<1];
    mar[node]=mar[node<<1|1];
    ma[node]=max(ma[node<<1],ma[node<<1|1]);
    int mid=(l+r)/2;
    if(a[mid]<a[mid+1]){
        if(mal[node<<1]==mid-l+1){
            mal[node]+=mal[node<<1|1];
        }
        if(mar[node<<1|1]==r-mid){
            mar[node]+=mar[node<<1];
        }
        ma[node]=max(ma[node],mar[node<<1]+mal[node<<1|1]);
    }
}
void build(int node,int l,int r){
    if(l==r){
        mal[node]=mar[node]=ma[node]=1;
        return ;
    }
    int mid=(l+r)/2;
    build(node<<1,l,mid);
    build(node<<1|1,mid+1,r);
    pushup(node,l,r);
}
void update(int node,int pos,int val,int l,int  r){
    if(l==r){
        return ;
    }
    int mid=(l+r)/2;
    if(mid>=pos) update(node<<1,pos,val,l,mid);
    else update(node<<1|1,pos,val,mid+1,r);
     pushup(node,l,r);
}
int query(int node,int L,int R,int l,int r){
    if(L<=l&&r<=R){
        return ma[node];
    }
    int mid=(l+r)/2,ans=0;
    if(mid>=L) ans=max(ans,query(node<<1,L,R,l,mid));
    if(mid<R) ans=max(ans,query(node<<1|1,L,R,mid+1,r));
    // 注意
    if(a[mid]<a[mid+1]){
       ans=max(ans,min(mid-L+1,mar[node<<1])+min(R-mid,mal[node<<1|1]));
    }
    return ans;
}
int main(){
    int _; cin>>_;
    while(_--){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }
        build(1,1,n);
        char opt;
        for(int i=1,x,y;i<=m;i++){
            getchar();
            cin>>opt>>x>>y;
            if(opt=='Q'){
                x++,y++;
                cout<<query(1,x,y,1,n)<<'\n';
            }else{
                x++;
                a[x]=y;
                update(1,x,y,1,n);
            }
        }
    }
    return 0;
}



上一篇:百度地图标记点 鼠标移入加名称


下一篇:HDU - 6934 Color the blocks