您的位置:首页 > 其它

HDU - 3308 LCIS(线段树)

2014-11-20 15:52 489 查看
单点修改,区间合并。

进行区间合并的时候注意讨论。

下面的代码给出了两种区间合并的姿势。

/*******************************
*hardbird's Personal Training  *
*Segment Tree                  *
*HDU - 3308 LCIS               *
*2014.11.19                    *
*******************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int maxn=110000;
int llen[maxn<<2], rlen[maxn<<2], mlen[maxn<<2], arr[maxn];

void pushup(int rt, int m, int mid)
{
    llen[rt]=llen[rt<<1];
    rlen[rt]=rlen[rt<<1|1];
    mlen[rt]=max(mlen[rt<<1], mlen[rt<<1|1]);
    if(arr[mid]<arr[mid+1])
    {
        if(llen[rt]==m-(m>>1))llen[rt]+=llen[rt<<1|1];
        if(rlen[rt]==m>>1)rlen[rt]+=rlen[rt<<1];
        mlen[rt]=max(mlen[rt], rlen[rt<<1]+llen[rt<<1|1]);
    }
}

void build(int l, int r, int rt)
{
    if(l==r)
    {
        scanf("%d", &arr[l]);
        llen[rt]=rlen[rt]=mlen[rt]=1;
        return ;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt, r-l+1, mid);
}

void update(int p, int v, int l, int r, int rt)
{
    int mid=(r+l)>>1;
    if(l==r)
    {
        arr[l]=v;
        return ;
    }
    if(p<=mid)update(p, v, lson);
    else update(p, v, rson);
    pushup(rt, r-l+1, mid);
}

int query(int L, int R, int l, int r, int rt)
{
    if(L<=l && R>=r)
        return mlen[rt];
    int mid=(l+r)>>1;
    if(R<=mid)return query(L, R, lson);
    if(L>mid)return query(L, R, rson);
    int a=min(rlen[rt<<1], mid-L+1);
    int b=min(llen[rt<<1|1], R-mid);
    if(arr[mid]<arr[mid+1])
        return max(a+b, max(query(L, R, lson), query(L, R, rson)));
    return max(query(L, R, lson), query(L, R, rson));
}

//int query(int L, int R, int l, int r, int rt)
//{
//    if(L<=l && R>=r)
//        return mlen[rt];
//    int mid=(l+r)>>1;
//    int ans=0;
//    if(L<=mid)ans=max(ans, query(L, R, lson));
//    if(R>mid)ans=max(ans, query(L, R, rson));
//    if(arr[mid]<arr[mid+1])
//        ans=max(ans, min(mid-L+1, rlen[rt<<1]) + min(R-mid, llen[rt<<1|1]));
//    return ans;
//}

int main()
{
    int n, m, T, a, b;
    char op[2];
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &m);
        build(1, n, 1);
        while(m--)
        {
            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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: