#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 100010
#define ls rt<<1
#define rs ls|1
#define m (l+r)>>1
int sum[MAX << 2];
int lsum[MAX << 2];
int rsum[MAX << 2];
int lb[MAX << 2];
int rb[MAX << 2];
int ans;
void uprt(int len,int rt)
{
int tg=0;
int l=rb[ls], r=lb[rs];
if (l<r)
tg = rsum[ls] + lsum[rs];
lb[rt] = lb[ls];
rb[rt] = rb[rs];
lsum[rt] = lsum[ls];
rsum[rt] = rsum[rs];
if (lsum[rt] == len - (len >> 1) && l<r)
lsum[rt] += lsum[rs];
if (rsum[rt] == (len >> 1) && l<r)
rsum[rt] += rsum[ls];
sum[rt] = max(tg, max(sum[ls], sum[rs]));
}
void updata(int q, int c, int l, int r, int rt)
{
if (l == r)
{
lb[rt] = rb[rt] = c;
return;
}
int mid = m;
if (q <= mid)
updata(q, c, l, mid, ls);
else
updata(q, c, mid + 1, r, rs);
uprt(r-l+1,rt);
}
void query(int& lsu,int& rsu,int& msu,int L, int R, int l, int r, int rt)
{
if (L <= l&&r <= R)
{
msu=sum[rt];
rsu = rsum[rt];
lsu = lsum[rt];
return;
}
int lsu1 = 0, rsu1 = 0, msu1 = 0;
int lsu2 = 0, rsu2 = 0, msu2 = 0;
int mid = m;
if (L <= mid)
query(lsu2,rsu2,msu2,L, R, l, mid, ls);
if (mid < R)
query(lsu1,rsu1,msu1,L, R, mid + 1, r, rs);
msu = max(msu1, msu2);
if (rsu2&&lsu1&&rb[ls] < lb[rs])
{
msu = max(msu, rsu2 + lsu1);
/*
合并之后,边界的考虑。
*/
if (lsu2 == (r - l + 1) - ((r - l + 1) >> 1))
lsu2 += lsu1;
if (rsu1 == ((r - l + 1) >> 1))
rsu1 += rsu2;
}
lsu = lsu2?lsu2:lsu1;
rsu = rsu1 ? rsu1:rsu2;
}
void build(int l, int r, int rt)
{
if (l == r)
{
scanf("%d", &lb[rt]);
rb[rt] = lb[rt];
sum[rt] = lsum[rt] = rsum[rt] = 1;
return;
}
int mid = m;
build(l, mid, ls);
build(mid + 1, r, rs);
uprt(r-l+1,rt);
}
int main()
{
int t;
cin >> t;
int n, k;
while (t--)
{
int lsu, rsu, msu;
scanf("%d%d", &n, &k);
n--;
build(0, n, 1);
char str[2];
int a, b;
while (k--)
{
scanf("%s%d%d", str, &a, &b);
if (str[0] == 'Q')
{
query(lsu, rsu, msu, a, b, 0, n, 1);
printf("%d\n", msu);
}
else
updata(a, b, 0, n, 1);
}
}
}
【HDU】3308 LCIS (线段树-区间合并)
最新推荐文章于 2019-03-04 10:35:01 发布