HDU3308

来源:互联网 发布:js 声明 字符串数组 编辑:程序博客网 时间:2024/06/04 19:47
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cstring>
#define MAX 111111
#define ll (p*2)
#define rr (ll+1)
#define mid ((t[p].l+t[p].r)/2)


using namespace std;


struct stree
{
    int l,r,c;  //左右端点,区间长度
    int ln,rn; //左右端点值
    int ls,rs,ms;
}t[MAX<<2];    //要乘2


int date[MAX];
void pushup(int p)
{
    t[p].ln=t[ll].ln;
    t[p].rn=t[rr].rn;
    t[p].ls=t[ll].ls;
    t[p].rs=t[rr].rs;
    t[p].ms=max(t[ll].ms,t[rr].ms);
    if (t[ll].rn<t[rr].ln)            //若两个区间的LCIS可以合并
    {
        if (t[ll].ls==t[ll].c) t[p].ls+=t[rr].ls;
        if (t[rr].rs==t[rr].c) t[p].rs+=t[ll].rs;
        t[p].ms=max(t[p].ms,t[ll].rs+t[rr].ls);
    }
}


void build(int p,int l,int r)
{
    t[p].l=l;
    t[p].r=r;
    t[p].c=r-l+1;
    if (l==r)
    {
        t[p].ln=t[p].rn=date[l];
        t[p].ls=t[p].rs=t[p].ms=1;
        return;
    }
    build(ll,l,mid);
    build(rr,mid+1,r);
    pushup(p);


}


void modify(int p,int po,int val)
{
    if (t[p].l==t[p].r)
    {
        t[p].ln=t[p].rn=val;
        return;
    }
    if (po>mid) modify(rr,po,val);
    else  modify(ll,po,val);
    pushup(p);
}


int  query(int p,int l,int r)
{
    if (t[p].l>=l&&t[p].r<=r) return t[p].ms;
    if (r<=mid) return query(ll,l,r);
    if (l>=mid+1) return query(rr,l,r);
    int ta,tb,ans=0;      //跨两个区间
    ta=query(ll,l,r);
    tb=query(rr,l,r);
    ans=max(ta,tb);
    if (t[ll].rn<t[rr].ln)
    {
        int l1,l2;
        l1=min(t[ll].rs,mid-l+1);
        l2=min(t[rr].ls,r-mid);
        ans=max(ans,l1+l2);
    }
    return ans;
}


int main()
{
    int T,n,m,i;
    char ch;
    freopen("in.txt","r",stdin);
    cin>>T;
    while (T--)
    {
        cin>>n>>m;
        for (i=1;i<=n;i++) cin>>date[i];
        build(1,1,n);
        while (m--)
        {
            int A,B;
            cin>>ch>>A>>B;
            if (ch=='Q') cout<<query(1,A+1,B+1)<<endl;
            else modify(1,A+1,B);
        }
    }
    //cout << "Hello world!" << endl;
    return 0;
}
/*题目大意:给n个数,
两种操作
1:U  a b   更新第a个为b (从0开始)
2: Q    a ,b  查询 a,b之间LCIS(最长连续递增子序列)的长度。
线段树:操作1是简单的单点更新,操作2 就是区间的查询,区间记录最长的连续递增子序列长度。
需要引进的变量
ls 当前区间从最左边起的最长连续递增子序列长度
rs 当前区间以最右边结尾的最长连续递增子序列长度
ms 当前区间最长连续递增子序列长度*/
0 0
原创粉丝点击