hdu 3308 LCIS(单点更新+区间合并)

来源:互联网 发布:数据分析师面试问题 编辑:程序博客网 时间:2024/05/06 03:51

题意:长度为N的数组,进行m次操作,

分为两种操作:

操作1:U A B 把位置A上的更新为B,

操作2: Q A B 输出[A,B]上的最长连续上升子序列


题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308


思路:

操作1,:单点更新

操作2:求连续的上升子序列,区间合并,

线段树节点维护三个值,这个子序列的左边开始的个数,右边开始的个数,这个区间的子序列的个数


和poj 3368多了一点在于单点更新~~~


#include <iostream>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define maxn 100010#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int n,m;int val[maxn];struct segnode{    int lnum,rnum,num;};segnode tree[maxn<<2];void PushUp(int rt,int l,int r){    int m = (l + r)/2;    tree[rt].lnum = tree[rt<<1].lnum;    tree[rt].rnum = tree[rt<<1|1].rnum;    tree[rt].num  = max(tree[rt<<1].num , tree[rt<<1|1].num);    if(val[m] < val[m+1]){        if(tree[rt<<1].lnum == (m - l + 1))            tree[rt].lnum += tree[rt<<1|1].lnum;        if(tree[rt<<1|1].rnum == (r - m))            tree[rt].rnum  += tree[rt<<1].rnum;        tree[rt].num = max(tree[rt].num,(tree[rt<<1].rnum + tree[rt<<1|1].lnum));    }}void build(int l,int r,int rt){    if(l == r){        tree[rt].lnum = 1;        tree[rt].rnum = 1;        tree[rt].num  = 1;        return ;    }    int m = (l + r)/2;    build(lson);    build(rson);    PushUp(rt,l,r);}void update(int pos,int c,int l,int r,int rt){    if(l == r){        val[pos] = c;        return ;    }    int m = (l + r)/2;    if(pos <= m) update(pos,c,lson);    else update(pos,c,rson);    PushUp(rt,l,r);}int query(int L,int R,int l,int r,int rt){    if(L <= l && r <= R){        return tree[rt].num;    }    int m = (l + r)/2;    if(R <= m) return query(L,R,lson);    else if(L > m) return query(L,R,rson);    else{        int lans = query(L,m,lson);        int rans = query(m+1,R,rson);        if(val[m] < val[m+1]){                int temp = min(tree[rt<<1].rnum ,(m - L + 1)) + min(tree[rt<<1|1].lnum , R - m);                return max(temp,max(lans,rans));        }        else{            return max(lans,rans);        }    }}int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%d %d",&n,&m);        for(int i=1;i<=n;i++)        scanf("%d",&val[i]);        build(1,n,1);        while(m--){            char op[10];            int a,b;            scanf("%s %d %d",op,&a,&b);            if(op[0]=='U'){                update(a+1,b,1,n,1);            }            else{                printf("%d\n",query(a+1,b+1,1,n,1));            }        }    }    return 0;}




原创粉丝点击