标签:
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6069 Accepted Submission(s): 2635
#include<iostream> #include<cstdio> #define N 100005 using namespace std; int MAX(int i,int j){ if(i>j) return i; return j; } int MIN(int i,int j){ if(i<j) return i; return j; } struct Tree{ int l,r; int lv,rv,mv; ///lv(rv)表示从最左(右)边起的最长连续递增子序列长度,mv表示该区间最大频率 }tree[4*N]; int a[N]; void PushUp(int l,int r,int idx){ tree[idx].lv = tree[idx<<1].lv; ///默认为左儿子的lv tree[idx].rv = tree[idx<<1|1].rv; ///默认为右儿子的rv tree[idx].mv = MAX(tree[idx<<1].mv,tree[idx<<1|1].mv);///对于父区间的mv值,默认是先在左右子区间的mx值中取一个较大值 int mid=(l+r)>>1; int len = r-l+1; ///区间长度 if(a[mid]<a[mid+1]){ ///两边可以进行合并 ///如果左子区间的lv等于左子区间的长度且可以延伸到右子区间,那么父区间的lv值等于左子区间 ///的lv加上右子区间的lv,否则,父区间的lv值就是左子区间的lv值,对于右子区间,同理 if(tree[idx].lv==len-(len>>1)) tree[idx].lv +=tree[idx<<1|1].lv; if(tree[idx].rv==(len>>1)) tree[idx].rv +=tree[idx<<1].rv; ///果左右区间能够延续,则在当前值和左子区间的rv+右子区间的lv之间取较大值 tree[idx].mv = MAX(tree[idx].mv,tree[idx<<1].rv+tree[idx<<1|1].lv); } } void build(int l,int r,int idx){ tree[idx].l = l; tree[idx].r = r; if(l==r){ tree[idx].lv = tree[idx].rv = tree[idx].mv = 1; return; } int mid = (l+r)>>1; build(l,mid,idx<<1); build(mid+1,r,idx<<1|1); PushUp(l,r,idx); } void update(int l,int r,int pos,int idx){ ///单点更新 if(l==r) { return; } int mid=(l+r)>>1; if(pos<=mid) update(l,mid,pos,idx<<1); else update(mid+1,r,pos,idx<<1|1); PushUp(l,r,idx); } int query(int l,int r,int idx){ if(tree[idx].l>=l&&tree[idx].r<=r){ return tree[idx].mv; } int mid=(tree[idx].l+tree[idx].r)>>1; int ans = 0; ///分别在左子区间和右子区间查找,结果分别为x,y,如果左右两个区间不能延续, ///那肯定是在x,y中找一个最大值 if(l<=mid) ans = MAX(ans,query(l,r,idx<<1)); ///x if(r>mid) ans = MAX(ans,query(l,r,idx<<1|1)); ///y ///如果能够延续,设两端延续区间长度为z,那么肯定是在 x,y,z找最大值,另外,对于左区间,我们要保证 ///向左延续的区间(rv)肯定是在[l,mid]中的(不然超过我们要查询的区间了),所以长度必须要在 mid - l+1之内 ///向右亦如此. if(a[mid]<a[mid+1]){ ans = MAX(ans,MIN(mid-l+1,tree[idx<<1].rv)+MIN(r-mid,tree[idx<<1|1].lv)); ///z } return ans; } int main() { int n,m; int tcase; scanf("%d",&tcase); while(tcase--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } build(1,n,1); //for(int i=1;i<=n;i++) printf("%d ",tree[i].mv); //printf("\n"); while(m--){ char s[5]; scanf("%s",s); if(s[0]==‘U‘){ int b,c; scanf("%d%d",&b,&c); a[++b] = c; ///由于题目下标从0开始,所以++ update(1,n,b,1); }else { int b,c; scanf("%d%d",&b,&c); b++,c++; printf("%d\n",query(b,c,1)); } } } return 0; }
标签:
原文地址:http://www.cnblogs.com/liyinggang/p/5351694.html