标签:
【题目大意】
查询最左端的连续长度区间;或批量修改一些区间。
【思路】
区间合并线段树……复习一下。POJ上有一样的题目,我居然还借用了别人的权限号去做BZOJ,简直愚昧到没朋友[笑cry]
处理方法以前的博文里有,这里有不赘述了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cstdlib> 6 using namespace std; 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 const int MAXN=55555+10; 10 int cover[MAXN<<2];//-1表示当前没有覆盖标记,1表示均覆盖为不可行,0表示均覆盖为可行 11 int lsum[MAXN<<2];//该区间从左起连续的可用区间长度的最大值 12 int msum[MAXN<<2];//该区间中连续的可用区间长度的最大值 13 int rsum[MAXN<<2];//该区间从右起连续的可用区间长度的最大值 14 15 void PushUp(int rt,int m) 16 { 17 lsum[rt]=lsum[rt<<1]; 18 if (lsum[rt]==m-(m>>1)) lsum[rt]+=lsum[rt<<1|1]; 19 rsum[rt]=rsum[rt<<1|1]; 20 if (rsum[rt]==m>>1) rsum[rt]+=rsum[rt<<1]; 21 msum[rt]=max(max(msum[rt<<1],msum[rt<<1|1]) , rsum[rt<<1]+lsum[rt<<1|1]); 22 } 23 24 void PushDown(int rt,int m) 25 { 26 if (cover[rt]!=-1) 27 { 28 cover[rt<<1]=cover[rt<<1|1]=cover[rt]; 29 if (cover[rt]==1) 30 { 31 msum[rt<<1]=lsum[rt<<1]=rsum[rt<<1]=0; 32 msum[rt<<1|1]=lsum[rt<<1|1]=rsum[rt<<1|1]=0; 33 } 34 else 35 { 36 msum[rt<<1]=lsum[rt<<1]=rsum[rt<<1]=m-(m>>1); 37 msum[rt<<1|1]=lsum[rt<<1|1]=rsum[rt<<1|1]=m>>1; 38 } 39 cover[rt]=-1; 40 } 41 } 42 43 44 int query(int w,int l,int r,int rt) 45 { 46 if (l==r) return l; 47 PushDown(rt,r-l+1); 48 int m=(l+r)>>1; 49 if (msum[rt<<1]>=w) return(query(w,lson)); 50 if (rsum[rt<<1]+lsum[rt<<1|1]>=w) return(m-rsum[rt<<1]+1); 51 if (msum[rt<<1|1]>=w) return(query(w,rson)); 52 return 0; 53 } 54 55 void update(int L,int R,int o,int l,int r,int rt) 56 { 57 if (L<=l && r<=R) 58 { 59 cover[rt]=o; 60 if (o==1) msum[rt]=lsum[rt]=rsum[rt]=0; 61 else msum[rt]=lsum[rt]=rsum[rt]=r-l+1; 62 return; 63 } 64 PushDown(rt,r-l+1);//这里是l和r,不要写成L和R 65 int m=(l+r)>>1; 66 if (L<=m) update(L,R,o,lson); 67 if (m<R) update(L,R,o,rson); 68 PushUp(rt,r-l+1); 69 } 70 71 void build(int l,int r,int rt) 72 { 73 msum[rt]=lsum[rt]=rsum[rt]=r-l+1; 74 cover[rt]=-1; 75 if (l==r) return; 76 int m=(l+r)>>1; 77 build(lson); 78 build(rson); 79 } 80 81 int main() 82 { 83 int n,m; 84 scanf("%d%d",&n,&m); 85 build(1,n,1); 86 for (int i=0;i<m;i++) 87 { 88 int op; 89 scanf("%d",&op); 90 if (op==1) 91 { 92 int w; 93 scanf("%d",&w); 94 if (msum[1]<w) cout<<0<<endl; 95 else 96 { 97 int p=query(w,1,n,1); 98 cout<<p<<endl; 99 update(p,p+w-1,1,1,n,1); 100 } 101 } 102 else 103 { 104 int u,v; 105 scanf("%d%d",&u,&v); 106 update(u,u+v-1,0,1,n,1); 107 } 108 } 109 return 0; 110 }
标签:
原文地址:http://www.cnblogs.com/iiyiyi/p/5664279.html