题目:http://acm.hdu.edu.cn/showproblem.php?pid=3308
题意:毫无疑问:经典的LICS 线段树区间更新
分析:
///毫无疑问:经典的LICS 线段树区间更新 /// 我们用lmax[rt] 表示 以左开端LIS,rmax[rt] 表示以右结尾的LIS,mmax[rt]表示全局的LIS #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int maxn=100002; #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r int lmax[maxn<<2],rmax[maxn<<2],mmax[maxn<<2],val[maxn],flag[maxn<<2],n,m,t; char s[2]; void pushup(int rt,int l,int r) { int mid=(l+r)>>1; lmax[rt]=lmax[rt<<1];///左孩子的以左开端的LIS rmax[rt]=rmax[rt<<1|1];///右孩子的以右结尾的LIS mmax[rt]=max(mmax[rt<<1],mmax[rt<<1|1]); if(val[mid]<val[mid+1]) { if(flag[rt<<1]) lmax[rt]+=lmax[rt<<1|1];///左孩子满,可以合并 if(flag[rt<<1|1])rmax[rt]+=rmax[rt<<1];///右孩子满,可以合并 mmax[rt]=max(mmax[rt],rmax[rt<<1]+lmax[rt<<1|1]);///右孩子左开端+左孩子右结尾 } if(mmax[rt]==r-l+1) flag[rt]=1; else flag[rt]=0; } void build(int rt,int l,int r) { lmax[rt]=rmax[rt]=mmax[rt]=flag[rt]=1; if(l==r) { scanf("%d",&val[l]); return; } int mid=(l+r)>>1; build(lson); build(rson); pushup(rt,l,r); } void updata(int rt,int l,int r,int idx,int num) { if(l==r) { val[idx]=num; return; } int mid=(l+r)>>1; if(mid>=idx) updata(lson,idx,num); else updata(rson,idx,num); pushup(rt,l,r); } int query(int rt,int l,int r,int L,int R) { if(L==l&&r==R) { return mmax[rt]; } int mid=(l+r)>>1; if(mid>=R) return query(lson,L,R); if(mid<L) return query(rson,L,R); int ans=max(query(lson,L,mid),query(rson,mid+1,R)); if(val[mid]<val[mid+1]) ans=max(ans,min(mid-L+1,rmax[rt<<1])+min(R-mid,lmax[rt<<1|1])); return ans; } void output() { for(int i=1;i<=n;i++) { cout<<val[i]<<" "; }cout<<endl; } int main() { cin>>t; while(t--) { scanf("%d%d",&n,&m); int i,j,a,b; build(1,1,n); //output(); for(i=1; i<=m; i++) { scanf("%s",&s); scanf("%d %d",&a,&b); if(s[0]=='Q') { printf("%d\n",query(1,1,n,a+1,b+1)); } else { updata(1,1,n,a+1,b); // output(); } } } return 0; } /* 2 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 */
代码: