线段树之LCIS

Description

Given n integers.
You have two operations:
U A B: replace the Ath number by B. (index counting from 0)
Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b].
 

Input

T in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=10 5).
The next line has n integers(0<=val<=10 5).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=10 5)
OR
Q A B(0<=A<=B< n).
 

Output

For each Q, output the answer.
 

Sample Input

1 10 10 7 7 3 3 5 9 9 8 1 8 Q 6 6 U 3 4 Q 0 1 Q 0 5 Q 4 7 Q 3 5 Q 0 2 Q 4 6 U 6 10 Q 0 9
 

Sample Output

1 1 4 2 3 1 2 5
 
 
 
#include<cstdio>
#include<iostream>
#include<cmath>

using namespace std;


typedef long long ll;
const int N=100010;
const ll INF=1e18;
int T,n,m,x,y;

char s[5];
int f[N<<2],le[N<<2],ri[N<<2];
int a[N];

void pushup(int root,int left,int right)
{
    int mid=(left+right)>>1;
    int rt=root<<1;
    
    if(le[rt]==mid-left+1&&a[mid]<a[mid+1]) {
        le[root]=le[rt]+le[rt+1];
    }
    else{
        le[root]=le[root<<1];
    } 
    
    if(ri[rt+1]==right-mid&&a[mid]<a[mid+1]){
        ri[root]=ri[rt]+ri[rt+1];
    } 
    else{
        ri[root]=ri[rt+1];
    } 
    
    f[root]=max(f[rt],f[rt+1]);
    
    if(a[mid]<a[mid+1]){
        f[root]=max(f[root],ri[rt]+le[rt+1]);
    } 
}

void build(int root,int left,int right)
{
    if(left==right)
    {
        scanf("%d",&a[left]);
        f[root]=le[root]=ri[root]=1;
        return;
    }
    
    int mid=left+right>>1;
    int rt=root<<1;
     
    build(rt,left,mid);
    build(rt+1,mid+1,right);
    
    pushup(root,left,right);
}

void updata(int root,int left,int right,int pos)
{
    int mid=left+right>>1;
    int rt=root<<1;
    
    if(left==right){
        return;
    } 
    
    if(pos<=mid){
        updata(rt,left,mid,pos);
    } 
    else{
        updata(rt+1,mid+1,right,pos);
    }
    
    pushup(root,left,right);
}

int query(int root,int qleft,int qright,int left,int right)
{
    if(left==qleft&&qright==right){
        return f[root];
    } 
    
    int mid=qleft+qright>>1;
    int rt=root<<1;
    
    if(right<=mid){
        return query(rt,qleft,mid,left,right);
    } 
    
    if(left>mid){
        return query(rt+1,mid+1,qright,left,right);
    } 
    
    int t1=query(rt,qleft,mid,left,mid);   
    int t2=query(rt+1,mid+1,qright,mid+1,right);
    
    int ans=max(t1,t2);
    
    if(a[mid]<a[mid+1]){
         ans= max(ans,min(ri[rt],mid-left+1)+min(le[rt+1],right-mid));
    }
       
    return ans;
}

int main()
{
    scanf("%d",&T);
    
    while(T--)
    {
        scanf("%d%d",&n,&m);
        
        build(1,0,n-1);
        
        while(m--)
        {
            scanf("%s%d%d",s,&x,&y);
            
            if(s[0]=='Q'){
                printf("%d\n",query(1,0,n-1,x,y));
            }
            else{
                a[x]=y;
                updata(1,0,n-1,x);
            }
        }
    }
    return 0;
}

 

posted @ 2022-07-18 22:32  killjoyskr  阅读(31)  评论(0)    收藏  举报