Description
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
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<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[1000000];
struct node
{
int l, r;int Llcis, Rlcis, lcis;int lnum, rnum;
}tree[4 * 10000001];
void pushup(int id)
{
if (tree[2 * id].rnum >= tree[2 * id + 1].lnum)
{
tree[id].Llcis = tree[2 * id].Llcis, tree[id].Rlcis = tree[2 * id + 1].Rlcis;
tree[id].lcis = max(tree[2*id].lcis, tree[2*id+1].lcis);
}
else
{
if ((tree[2 * id].r - tree[2 * id].l + 1) == tree[2 * id].Llcis)
tree[id].Llcis = tree[2 * id].Llcis + tree[2 * id + 1].Llcis;
else tree[id].Llcis = tree[2 * id].Llcis;
if ((tree[2 * id + 1].r - tree[2 * id + 1].l + 1) == tree[2 * id + 1].Rlcis)
tree[id].Rlcis = tree[2 * id + 1].Rlcis + tree[2 * id].Rlcis;
else tree[id].Rlcis = tree[2 * id + 1].Rlcis;
int t1 = tree[2 * id].Rlcis + tree[2 * id + 1].Llcis;
int t2 = max(tree[id].Llcis, tree[id].Rlcis), t3 = max(tree[2 * id].lcis, tree[2 * id + 1].lcis);
tree[id].lcis = max(t1, max(t3, t2));
}
}
void build(int id, int l, int r)
{
tree[id].l = l, tree[id].r = r;
if (tree[id].l == tree[id].r)
{
tree[id].lnum = tree[id].rnum = a[l];
tree[id].Llcis = tree[id].Rlcis = tree[id].lcis = 1;
return;
}
int mid = (tree[id].l + tree[id].r) / 2;
build(2 * id, l, mid);build(2 * id + 1, mid + 1, r);
tree[id].lnum = tree[2 * id].lnum, tree[id].rnum = tree[2 * id + 1].rnum;
pushup(id);
}
void update(int id, int pos, int val)
{
if (tree[id].l == tree[id].r)
{
tree[id].lnum = tree[id].rnum = val;
return;
}
int mid = (tree[id].l + tree[id].r) / 2;
if (pos <= mid) update(2 * id, pos, val);
else update(2 * id + 1, pos, val);
tree[id].lnum = tree[2 * id].lnum, tree[id].rnum = tree[2 * id + 1].rnum;
pushup(id);
}
int query(int id, int l, int r)
{
if (tree[id].l == l&&tree[id].r == r)
return tree[id].lcis;
if (r <= (tree[id].l + tree[id].r) / 2) return query(2 * id, l, r);
else if (l > (tree[id].l + tree[id].r) / 2) return query(2 * id + 1, l, r);
else
{
int mid = (tree[id].l + tree[id].r) / 2, Lmax, Rmax;
Lmax = query(2 * id, l, mid), Rmax = query(2 * id + 1, mid + 1, r);
if (tree[2 * id].rnum >= tree[2 * id + 1].lnum) return max(Lmax, Rmax);
else
{
int ans = 0;
ans = min(mid - l + 1, tree[2 * id].Rlcis) + min(r - mid, tree[2 * id + 1].Llcis);
return max(ans, max(Lmax, Rmax));
}
}
}
int main()
{
int t, n, q, i, x, y;char c;
cin >> t;
while (t--)
{
cin >> n >> q;
for (i = 1;i <= n;i++)
cin >> a[i];
build(1, 1, n);
for (i = 0;i < q;i++)
{
cin >> c;
if (c == 'Q')
{
cin >> x >> y;
printf("%d\n", query(1, x + 1, y + 1));
}
if (c == 'U')
{
cin >> x >> y;
update(1, x + 1, y);
}
}
}
return 0;
}