hdu3308LCIS 线段树

来源:互联网 发布:淘宝新赛欧改折叠钥匙 编辑:程序博客网 时间:2024/06/15 17:04
//U A B 将第A位置的元素改为B//Q A B询问[A , B]区间的最长的递增序列//维护ma_l , ma , ma_r 左边最长,区间最长,右边最长#include<cstdio>#include<cstring>#include<iostream>using namespace std ;const int maxn = 1e5 + 10 ;#define left v<<1#define right v<<1|1struct node{    int l , r ;    int ma_l , ma_r , ma ;}tree[maxn<<2] ;int h[maxn] ;int T ;int n , m ;void push_up(int v){    tree[v].ma_l = tree[left].ma_l ;    tree[v].ma_r = tree[right].ma_r ;    tree[v].ma = max(tree[left].ma , tree[right].ma) ;    if(h[tree[left].r] < h[tree[right].l])    {        tree[v].ma = max(tree[v].ma , tree[left].ma_r + tree[right].ma_l) ;        if(tree[left].r - tree[left].l + 1 == tree[v].ma_l)        tree[v].ma_l += tree[right].ma_l ;        if(tree[right].r - tree[right].l + 1 == tree[v].ma_r)        tree[v].ma_r += tree[left].ma_r ;    }}void build(int l , int r , int v){    tree[v].l = l ;    tree[v].r = r;    if(l == r)    {        tree[v].ma_l = tree[v].ma = tree[v].ma_r = 1 ;        return ;    }    int mid = (l + r) >> 1 ;    build(l , mid , left) ;    build(mid + 1 , r , right) ;    push_up(v) ;}int query(int v , int l , int r){    if(l <= tree[v].l && tree[v].r <= r)    return tree[v].ma ;    int mid = (tree[v].l + tree[v].r) >> 1 ;    int ans_1 = 0 , ans_2 = 0 ,ans_3 = 0 ;    if(l <= mid)ans_1 = query(left , l , r) ;    if(r > mid)ans_2 = query(right , l , r) ;    int ans = max(ans_1 , ans_2) ;    if(h[tree[left].r] < h[tree[right].l])    {        ans_3 = min(tree[left].ma_r , tree[left].r - l + 1) + min(tree[right].ma_l , r - tree[right].l + 1) ;        ans = max(ans , ans_3) ;    }    return ans ;}void update(int pos , int num ,int v){    if(tree[v].l == tree[v].r)    {        h[pos] = num ;        return  ;    }    int mid = (tree[v].l + tree[v].r) >> 1 ;    if(pos <= mid)update(pos , num , left);    else if(pos > mid)update(pos ,num ,right) ;    push_up(v) ;}int main(){   // freopen("in.txt" ,"r" ,stdin) ;    scanf("%d" , &T) ;    while(T--)    {        scanf("%d%d" ,&n , &m) ;        for(int i = 1;i <= n;i++)        scanf("%d" , &h[i]) ;        build(1 , n , 1) ;        char ch[10] ;int a , b ;        while(m--)        {            scanf("%s" ,ch) ;            scanf("%d%d" ,&a , &b) ;            if(ch[0] == 'Q')            printf("%d\n" ,query(1 , a  + 1, b + 1));            else if(ch[0] == 'U')            update(a+1 , b , 1) ;        }    }    return 0 ;}
0 0
原创粉丝点击