HDU 3308——LCIS(线段树,区间合并,最长连续递增子序列)

LCIS

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4255    Accepted Submission(s): 1938


Problem 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
 


—————————————————————分割线——————————————————————


题目大意:

给定一个序列,有两种操作

1:U a b 将第a个元素的值改为b(下标从0开始)

2:Q a b 查询区间[a,b]的最长连续递增子序列的长度


思路:

维护某个节点区间的 左连续递增区间长度,右连续递增区间长度,总的连续递增区间长度

然后简单的查询   左、中、右 具有相同的优先级


因为修改为单点修改,因此要更新到叶子节点,push_up


虽然自己知道思路,打来打去小细节害死人啊


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=100001;
using namespace std;

int lc[maxn<<2],rc[maxn<<2],mc[maxn<<2];
int lnum[maxn<<2],rnum[maxn<<2];
void push_up(int rt,int m)
{
    lnum[rt]=lnum[rt<<1];
    rnum[rt]=rnum[rt<<1|1];
    lc[rt]=lc[rt<<1];
    rc[rt]=rc[rt<<1|1];
    mc[rt]=max(mc[rt<<1],mc[rt<<1|1]);
    if(rnum[rt<<1]<lnum[rt<<1|1]){
        if(lc[rt]==(m-(m>>1))) lc[rt]+=lc[rt<<1|1];
        if(rc[rt]==(m>>1)) rc[rt]+=rc[rt<<1];
        mc[rt]=max(lc[rt<<1|1]+rc[rt<<1],mc[rt]);
    }
}
void build(int l,int r,int rt)
{

    if(l==r){
        scanf("%d",&lnum[rt]);
        rnum[rt]=lnum[rt];
        mc[rt]=lc[rt]=rc[rt]=1;
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    push_up(rt,r-l+1);
}
void update(int p,int modify,int l,int r,int rt)
{
    if(l==r){
        lnum[rt]=rnum[rt]=modify;
        return ;
    }
    int m=(l+r)>>1;
    if(p<=m) update(p,modify,lson);
    else update(p,modify,rson);
    push_up(rt,r-l+1);
}
int query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R){
        return mc[rt];
    }
    int m=(l+r)>>1;
    int maxx=0;
    if(L<=m)
        maxx=max(maxx,query(L,R,lson));
    if(m<R)
        maxx=max(maxx,query(L,R,rson));
    if(rnum[rt<<1]<lnum[rt<<1|1])
        maxx=max(maxx,min(m-L+1,rc[rt<<1])+min(R-m,lc[rt<<1|1]));
    return maxx;
}
int main()
{
    int T,n,m;
    cin>>T;
    while(T--){
        scanf("%d %d",&n,&m);
        build(0,n-1,1);
        char op[2];int a,b;
        while(m--){
            scanf("%s %d %d",op,&a,&b);
            if(op[0]=='U') update(a,b,0,n-1,1);
            else printf("%d\n",query(a,b,0,n-1,1));
        }
    }
    return 0;
}




你可能感兴趣的:(HDU 3308——LCIS(线段树,区间合并,最长连续递增子序列))