hdu 3308 LCIS(区间合并)

来源:互联网 发布:淘宝上传照片大小 编辑:程序博客网 时间:2024/06/08 12:42

题目链接: hdu 3308 LCIS

题意:求给定区间最大上升序列的个数

#include<iostream>#include<cstdio>#define maxn 111111#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;int lsum[maxn<<2],rsum[maxn<<2],msum[maxn<<2];int ln[maxn<<2],rn[maxn<<2]; //ln存储区间最左边开始的上升系数,rn记录区间从右开始的上升序列数void pushup(int rt,int m){    lsum[rt]=lsum[rt<<1];    rsum[rt]=rsum[rt<<1|1];    msum[rt]=max(msum[rt<<1],msum[rt<<1|1]);    ln[rt]=ln[rt<<1];  //父区间最左边的上升数就是就是子节点的数,右边同理    rn[rt]=rn[rt<<1|1];    if(rn[rt<<1]<ln[rt<<1|1] )  //当左儿子的最右端的值小于右儿子最左端的值,把这两段区间相连    {        if(lsum[rt]==(m-(m>>1)))    lsum[rt]+=lsum[rt<<1|1]; //左儿子的值等于区间个数,父区间的长度为左儿子区间加上右儿子的左区间         if(rsum[rt]==(m>>1))         rsum[rt]+=rsum[rt<<1];  //右区间同理        msum[rt]=max(msum[rt],rsum[rt<<1]+lsum[rt<<1|1]);//更改整个区间长度    }}void build(int l,int r,int rt){    if(l==r)    {        scanf("%d",&ln[rt]);        rn[rt]=ln[rt];        lsum[rt]=rsum[rt]=msum[rt]=1;//叶子节点初始个数都为一        return ;    }    int m =(l+r)>>1;    build(lson);    build(rson);    pushup(rt,r-l+1);    //printf("msum[%d %d] = %d\n",l,r,msum[rt]);}void update(int p,int c,int l,int r,int rt){    if(l==r)    {        ln[rt]=rn[rt]=c;        lsum[rt]=rsum[rt]=msum[rt]=1;        return ;    }    int m =(l+r)>>1;    if(p<=m) update(p,c,lson);    else update(p,c,rson);    pushup(rt,r-l+1);}int query(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R)  return msum[rt];    int m=(l+r)>>1;    int ret = -1;    if(L<=m)  ret=max(ret,query(L,R,lson));    if(R>m)    ret=max(ret,query(L,R,rson));    if(rn[rt<<1]<ln[rt<<1|1])    ret=max(ret,min(rsum[rt<<1],m-L+1)+min(lsum[rt<<1|1],R-m));//左右儿子相连时,长度应为相连总和,但要考虑到该区间的左右啦;两边可能与其他区间相连,所以长度可能会超过此区间的长度   // printf("msum[%d %d] = %d , ret = %d\n",l,r,msum[rt],ret);    return ret;}int main(){    int t,n,m;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        build(1,n,1);        while(m--)        {            char op;            int a,b;            scanf(" %c%d%d",&op,&a,&b);            if(op=='Q')  printf("%d\n",query(a+1,b+1,1,n,1));            else update(a+1,b,1,n,1);        }    }    return 0;}


0 0
原创粉丝点击