Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3553 Accepted Submission(s): 1577
#include <stdio.h> #include <stdlib.h> #include <algorithm> #include <iostream> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define maxn 100005 using namespace std; int mov[maxn<<2],las[maxn<<2],ras[maxn<<2]; int va[maxn]; void pushup(int rt,int l,int r) { las[rt]=las[rt<<1]; ras[rt]=ras[rt<<1|1]; mov[rt]=max(mov[rt<<1],mov[rt<<1|1]); int mid=(l+r)>>1; int m=(r-l)+1; if(va[mid]<va[mid+1]) //左区间的右值小于右区间的左值可以合并 { if(las[rt]==m-(m>>1)) las[rt]+=las[rt<<1|1]; if(ras[rt]==(m>>1)) ras[rt]+=ras[rt<<1]; mov[rt]=max(mov[rt],las[rt<<1|1]+ras[rt<<1]); } } void build(int l,int r,int rt) { if(l==r) { mov[rt]=las[rt]=ras[rt]=1; return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt,l,r); } void update(int a,int l,int r,int rt) { if(l==r) { return; } int m=(l+r)>>1; if(a<=m) update(a,lson); else update(a,rson); pushup(rt,l,r); } int query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) { return mov[rt]; } int m=(l+r)>>1; if(R<=m) return query(L,R,lson); //与一般不同,不能是子集,只能全部属于才能直接查询子区间 返回子区间的mlen if(L>m) return query(L,R,rson); //否则是确认儿子区间是否能合并,并在三者之间取最大值 int ta,tb; ta=query(L,R,lson); tb=query(L,R,rson); int ans; ans=max(ta,tb); if(va[m]<va[m+1]) //同上 { int temp; temp=min(ras[rt<<1],m-L+1)+min(las[rt<<1|1],R-m); ans=max(temp,ans); } return ans; } int main() { int T,n,m; int i,j; char f[2]; int a,b; scanf("%d",&T); for(i=0;i<T;i++) { scanf("%d %d",&n,&m); for(j=1;j<=n;j++) scanf("%d",&va[j]); build(1,n,1); while(m--) { scanf("%s",&f); if(f[0]=='U') { scanf("%d %d",&a,&b); a++; va[a]=b; update(a,1,n,1); } else { scanf("%d %d",&a,&b); a++,b++; printf("%d\n",query(a,b,1,n,1)); } } } return 0; }