#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 当前区间最长连续递增子序列长度*/
#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 当前区间最长连续递增子序列长度*/