Given n integers.
You have two operations:
U A B: replace the Ath number by B. (index counting from 0)
Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b].
Input
T in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=10 5).
The next line has n integers(0<=val<=10 5).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=10 5)
OR
Q A B(0<=A<=B< n).
Output
For each Q, output the answer.
Sample Input
1
10 10
7 7 3 3 5 9 9 8 1 8
Q 6 6
U 3 4
Q 0 1
Q 0 5
Q 4 7
Q 3 5
Q 0 2
Q 4 6
U 6 10
Q 0 9
Sample Output
1
1
4
2
3
1
2
5
题意:
单点修改。询问区间最长上升子串
思路:
维护区间最长上升串,区间最长上升前缀,区间最长上升后缀。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 7;
struct Node
{
int l,r;
int lx,rx,mx;
}t[maxn << 2];
int val[maxn];
void pushup(int i)
{
int m = (t[i].l + t[i].r) >> 1;
//mx
t[i].mx = max(t[i * 2].mx,t[i * 2 + 1].mx);
if(val[m] < val[m + 1])t[i].mx = max(t[i].mx,t[i * 2].rx + t[i * 2 + 1].lx);
//lx
t[i].lx = t[i * 2].lx;
if(val[m] < val[m + 1] && t[i * 2].lx == m - t[i * 2].l + 1)
t[i].lx += t[i * 2 + 1].lx;
//rx
t[i].rx = t[i * 2 + 1].rx;
if(val[m] < val[m + 1] && t[i * 2 + 1].rx == t[i * 2 + 1].r - m)
t[i].rx += t[i * 2].rx;
}
void build(int i,int l,int r)
{
t[i].l = l;t[i].r = r;
if(l == r)
{
t[i].lx = t[i].rx = t[i].mx = 1;
scanf("%d",&val[l]);
return;
}
int m = (l + r) >> 1;
build(i * 2,l,m);
build(i * 2 + 1,m + 1,r);
pushup(i);
}
void update(int i,int x,int v)
{
if(t[i].l == t[i].r)
{
val[t[i].l] = v;
return;
}
int m = (t[i].l + t[i].r) >> 1;
if(x <= m)update(i * 2,x,v);
else update(i * 2 + 1,x,v);
pushup(i);
}
int query(int i,int x,int y)
{
if(x <= t[i].l && t[i].r <= y)
{
return t[i].mx;
}
int m = (t[i].l + t[i].r) >> 1;
if(y <= m)return query(i * 2,x,y);
if(x > m) return query(i * 2 + 1,x,y);
int x1 = query(i * 2,x,y), x2 = query(i * 2 + 1,x,y);
int l = min(t[i * 2].rx,m - x + 1);
int r = min(t[i * 2 + 1].lx,y - m);
int x3 = l;
if(val[m] < val[m + 1])x3 += r;
return max(max(x1,x2),x3);
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
int n,m;scanf("%d%d",&n,&m);
build(1,1,n);
while(m--)
{
char op[10];
int x,y;
scanf("%s %d %d",op,&x,&y);
if(op[0] == 'Q')
{
x++;y++;
printf("%d\n",query(1,x,y));
}
else if(op[0] == 'U')
{
x++;
update(1,x,y);
}
}
}
return 0;
}