UESTC 1425 Another LCIS
来源:互联网 发布:linux权限命令 编辑:程序博客网 时间:2024/05/05 16:00
也是一个求最长连续单调区间的问题,不同于HDU 3308LCIS的是,单点更新变成了区间成段增加,没关系同样的方法可破之。由于是成段更新,所以比更新区间小的区间是最大连续区间长度是不变的,所以更新sum[rt],lsum[rt],rsum[rt]只需要更新到这些区间,然后向上合并就行了。
但是速度还是慢了一点699ms,总觉得哪里还有改进的地方。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 #define N 111111 7 8 using namespace std; 9 int sum[N<<2],lsum[N<<2],rsum[N<<2],add[N<<2],A[N]; 10 int n,q; 11 12 void PushUp(int rt,int m,int mid) 13 { 14 lsum[rt]=lsum[rt<<1]; 15 rsum[rt]=rsum[rt<<1|1]; 16 int t=1; 17 if(A[mid+1]>A[mid]) 18 { 19 if(lsum[rt]==(m-(m>>1))) 20 lsum[rt]+=lsum[rt<<1|1]; 21 if(rsum[rt]==(m>>1)) 22 rsum[rt]+=rsum[rt<<1]; 23 t=rsum[rt<<1]+lsum[rt<<1|1]; 24 } 25 sum[rt]=max(t,max(sum[rt<<1],sum[rt<<1|1])); 26 } 27 28 void build(int l,int r,int rt) 29 { 30 if(l==r) 31 { 32 scanf("%d",A+l); 33 sum[rt]=lsum[rt]=rsum[rt]=1; 34 return ; 35 } 36 int m=(l+r)>>1; 37 build(lson); 38 build(rson); 39 PushUp(rt,r-l+1,m); 40 } 41 42 void update(int L,int R,int l,int r,int rt) 43 { 44 if(L<=l&&R>=r) 45 return; 46 int m=(l+r)>>1; 47 if(L<=m) 48 update(L,R,lson); 49 if(R>m) 50 update(L,R,rson); 51 PushUp(rt,r-l+1,m); 52 } 53 54 int query(int L,int R,int l,int r,int rt) 55 { 56 if(L<=l&&R>=r) 57 return sum[rt]; 58 int m=(l+r)>>1; 59 int ans=0; 60 if(R<=m) 61 ans=max(ans,query(L,R,lson)); 62 else if(L>m) 63 ans=max(ans,query(L,R,rson)); 64 else 65 { 66 ans=max(ans,query(L,R,lson)); 67 ans=max(ans,query(L,R,rson)); 68 int ll,rr; 69 if(m-L+1>=rsum[rt<<1]) 70 ll=rsum[rt<<1]; 71 else ll=m-L+1; 72 if(R-m>=lsum[rt<<1|1]) 73 rr=lsum[rt<<1|1]; 74 else rr=R-m; 75 if(A[m+1]>A[m]) 76 ans=max(ans,ll+rr); 77 } 78 return ans; 79 } 80 81 int main(void) 82 { 83 int T; 84 int a,b,v; 85 char op[3]; 86 for(int t=scanf("%d",&T); t<=T; t++) 87 { 88 memset(add,0,sizeof(add)); 89 printf("Case #%d:\n",t); 90 scanf("%d%d",&n,&q); 91 build(1,n,1); 92 while(q--) 93 { 94 scanf("%s",op); 95 if(op[0]=='a') 96 { 97 scanf("%d%d%d",&a,&b,&v); 98 for(int i=a;i<=b;i++) 99 A[i]+=v;100 update(a,b,1,n,1);101 }102 else103 {104 scanf("%d%d",&a,&b);105 int ans=query(a,b,1,n,1);106 printf("%d\n",ans);107 }108 }109 }110 return 0;111 }
方法二:看了下别人代码,发现每个区间可以用left[rt],right[rt]将区间端点值存起来,这样每次更新的时候更新端点值就可以了:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 #define N 111111 7 8 using namespace std; 9 int sum[N<<2],lsum[N<<2],rsum[N<<2],add[N<<2],left[N<<2],right[N<<2]; 10 int n,q; 11 12 void PushUp(int rt,int m) 13 { 14 left[rt]=left[rt<<1]; 15 right[rt]=right[rt<<1|1]; 16 lsum[rt]=lsum[rt<<1]; 17 rsum[rt]=rsum[rt<<1|1]; 18 int t=1; 19 if(left[rt<<1|1]>right[rt<<1]) 20 { 21 if(lsum[rt]==(m-(m>>1))) 22 lsum[rt]+=lsum[rt<<1|1]; 23 if(rsum[rt]==(m>>1)) 24 rsum[rt]+=rsum[rt<<1]; 25 t=rsum[rt<<1]+lsum[rt<<1|1]; 26 } 27 sum[rt]=max(t,max(sum[rt<<1],sum[rt<<1|1])); 28 } 29 void PushDown(int rt) 30 { 31 if(add[rt])//这里用来向下更新add[rt], 32 { 33 add[rt<<1]+=add[rt]; 34 add[rt<<1|1]+=add[rt]; 35 left[rt<<1]+=add[rt]; 36 right[rt<<1]+=add[rt]; 37 left[rt<<1|1]+=add[rt]; 38 right[rt<<1|1]+=add[rt]; 39 add[rt]=0; 40 } 41 42 } 43 void build(int l,int r,int rt) 44 { 45 add[rt]=0; 46 if(l==r) 47 { 48 scanf("%d",left+rt); 49 right[rt]=left[rt]; 50 sum[rt]=lsum[rt]=rsum[rt]=1; 51 return ; 52 } 53 int m=(l+r)>>1; 54 build(lson); 55 build(rson); 56 PushUp(rt,r-l+1); 57 } 58 59 void update(int L,int R,int v,int l,int r,int rt) 60 { 61 if(L<=l&&R>=r) 62 { 63 left[rt]+=v; 64 right[rt]+=v; 65 add[rt]+=v; 66 return; 67 } 68 int m=(l+r)>>1; 69 PushDown(rt); 70 if(L<=m) 71 update(L,R,v,lson); 72 if(R>m) 73 update(L,R,v,rson); 74 PushUp(rt,r-l+1); 75 } 76 77 int query(int L,int R,int l,int r,int rt) 78 { 79 if(L<=l&&R>=r) 80 return sum[rt]; 81 PushDown(rt); 82 int m=(l+r)>>1; 83 int ans=0; 84 if(R>m) 85 ans=max(ans,query(L,R,rson)); 86 if(L<=m) 87 ans=max(ans,query(L,R,lson)); 88 if(left[rt<<1|1]>right[rt<<1]&&L<=m&&R>m) 89 { 90 int ll,rr; 91 if(m-L+1>=rsum[rt<<1]) 92 ll=rsum[rt<<1]; 93 else ll=m-L+1; 94 if(R-m>=lsum[rt<<1|1]) 95 rr=lsum[rt<<1|1]; 96 else rr=R-m; 97 ans=max(ans,ll+rr); 98 } 99 return ans;100 }101 102 int main(void)103 {104 int T;105 int a,b,v;106 char op[3];107 for(int t=scanf("%d",&T); t<=T; t++)108 {109 memset(add,0,sizeof(add));110 printf("Case #%d:\n",t);111 scanf("%d%d",&n,&q);112 build(1,n,1);113 while(q--)114 {115 scanf("%s",op);116 if(op[0]=='a')117 {118 scanf("%d%d%d",&a,&b,&v);119 update(a,b,v,1,n,1);120 }121 else122 {123 scanf("%d%d",&a,&b);124 int ans=query(a,b,1,n,1);125 printf("%d\n",ans);126 }127 }128 }129 return 0;130 }
0 0
- UESTC 1425 Another LCIS
- UESTC 1425 Another LCIS
- UESTC - 1425 Another LCIS
- UESTC 1425 Another LCIS
- uestc 1425——Another LCIS
- UESTC 360(1425) another LCIS
- 【37.07%】【UESTC 360】Another LCIS
- uestc 1425 Another LCIS(线段树 最长递增序列)
- uestc 1425 Another LCIS(成段更新)
- uestc Another LCIS 区间线段树
- UESTC 360 Another LCIS 线段树
- UESTC 360 Another LCIS (线段树 维护LCIS)
- [UESTC]Another LCIS[线段树][区间合并][成段修改]
- uestc Another LCIS(区间更新,区间合并)
- UESTC 360 Another LCIS(线段树区间更新)
- UESTC 360 Another LCIS(线段树 x 经典区间合并姿势)
- 【线段树】Another LCIS
- UESTC1425 Another LCIS
- poj 3225 Help with Intervals
- 编程习惯记录
- poj1436 Horizontally Visible Segments
- poj crane
- hdu 3308 LCIS
- UESTC 1425 Another LCIS
- HDU 3397 Sequence operation
- SGU 488 Dales and Hills
- UVA 10896 Sending Email
- 解决UIScrollView滚动和子视图手势冲突的方案
- UVA 10801 Lift Hopping
- UVA 558 Wormholes
- UVA 515 King
- UVA 125 Numbering Paths