1Y爽歪歪
线段树功能:1. 单点更新 2.查询区间递增子序列长度
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define for if(0); else for
const int N=100010;
struct SegNode{
int lval,rval;
int lsum,rsum,csum;
bool flag;
SegNode(){lval=rval=0,lsum=rsum=csum=1,flag=false;}
};
struct SegTree{
SegNode a[N<<2];
int n,Q;
void Init(int n){
for(Q=1;Q<=n+2;Q<<=1);
this->n=n;
for(int i=0;i<=Q<<1;i++) a[i]=SegNode();
}
void pushup(int rt,int L){
if(rt>=Q) return;
a[rt]=merge(a[rt<<1],a[rt<<1|1],L);
}
SegNode merge(SegNode l,SegNode r,int L){
if(l.flag==1) return r;
SegNode ret=SegNode();
ret.lval=l.lval;
ret.rval=r.rval;
ret.lsum=l.lsum;
ret.rsum=r.rsum;
ret.csum=max(l.csum,r.csum);
if(l.rval<r.lval){
if(ret.lsum==L>>1) ret.lsum+=r.lsum;
if(ret.rsum==L>>1) ret.rsum+=l.rsum;
ret.csum=max(ret.csum,l.rsum+r.lsum);
}
ret.csum=max(ret.csum,max(ret.lsum,ret.rsum));
return ret;
}
SegNode query(int L,int R,int l,int r,int rt){
SegNode ret;
ret.flag=true;
if(L<=l&& r<=R){
return a[rt];
}
if(rt>=Q) return ret;
int m=(l+r)>>1;
if(L<=m) ret=merge(ret,query(L,R,l,m,rt<<1),r-l+1);
if(m<R) ret=merge(ret,query(L,R,m+1,r,rt<<1|1),r-l+1);
return ret;
}
void update(int pos,int x){
pos+=Q;
a[pos].lval=a[pos].rval=x;pos>>=1;
int L=2;
while(pos) a[pos]=merge(a[pos<<1],a[pos<<1|1],L),L<<=1,pos>>=1;
}
SegNode query(int L,int R){
return query(L,R,0,Q-1,1);
}
}st;
int T,n,m;
int main() {
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
st.Init(n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
st.update(i,x);
}
for(int i=1;i<=m;i++){
char cmd;
int l,r;
scanf(" %c %d %d",&cmd,&l,&r);
if(cmd=='U'){
st.update(l+1,r);
}else if(cmd=='Q'){
SegNode ans=st.query(l+1,r+1);
printf("%d\n",ans.csum);
}
}
}
return 0;
}