第一个二分查找的是第num个0,第二个二分查找的是最后一个0
把lrj大白书里的线段树重打一遍成以后模板,关于里面的maintain函数:
1 #include2 #include<string.h> 3 #include 4 using namespace std; 5 int n,ll; 6 int setv[200005],sumv[200005]; 7 int query(int o,int l,int r,int y1,int y2) 8 { 9 if (setv[o]>=0) return setv[o]*(min(r,y2)-max(l,y1)+1); 10 else if (y1<=l&&y2>=r) return sumv[o]; 11 else{ 12 int mid=l+(r-l)/2,tmp=0; 13 if (y1<=mid) tmp+=query(o*2,l,mid,y1,y2); 14 if (y2>mid) tmp+=query(o*2+1,mid+1,r,y1,y2); 15 return tmp; 16 } 17 } 18 void maintain(int o,int l,int r) 19 { 20 sumv[o]=0; 21 if (setv[o]>=0) sumv[o]=setv[o]*(r-l+1); 22 else sumv[o]=sumv[o*2]+sumv[o*2+1]; 23 } 24 void update(int o,int l,int r,int y1,int y2,int v) 25 { 26 int mid=l+(r-l)/2; 27 if (y1<=l&&y2>=r) setv[o]=v; 28 else{ 29 if (setv[o]>=0){ 30 setv[o*2]=setv[o*2+1]=setv[o]; 31 setv[o]=-1; 32 } 33 if (y1<=mid) update(o*2,l,mid,y1,y2,v); 34 else maintain(o*2,l,mid); 35 if (y2>mid) update(o*2+1,mid+1,r,y1,y2,v); 36 else maintain(o*2+1,mid+1,r); 37 } 38 maintain(o,l,r); 39 } 40 int left_search(int l,int r,int num) 41 { 42 int mid=l+(r-l)/2; 43 if (l==r) return l; 44 int tmp=query(1,1,n,ll,mid); 45 if (tmp+num<=mid-ll+1) return left_search(l,mid,num); 46 return left_search(mid+1,r,num); 47 } 48 int right_search(int l,int r) 49 { 50 int mid=l+(r-l)/2+1; 51 if (l==r) return l; 52 int tmp=query(1,1,n,mid,n); 53 if (tmp+1<=n-mid+1) return right_search(mid,r); 54 return right_search(l,mid-1); 55 } 56 int main() 57 { 58 int T,m,k,x,y,tmp,tl,tr; 59 scanf("%d",&T); 60 while (T--) 61 { 62 scanf("%d%d",&n,&m); 63 memset(sumv,0,sizeof(sumv)); 64 memset(setv,-1,sizeof(setv)); 65 while (m--) 66 { 67 scanf("%d%d%d",&k,&x,&y); 68 if (k==2) 69 { 70 x++; y++; 71 tmp=query(1,1,n,x,y); 72 printf("%d\n",tmp); 73 update(1,1,n,x,y,0); 74 } 75 else{ 76 x++; 77 tmp=query(1,1,n,x,n); 78 if (tmp==n-x+1) { 79 printf("Can not put any one.\n"); 80 continue; 81 } 82 ll=x; 83 if (n-x+1-tmp right_search(x,n); 84 else tr=left_search(x,n,y); 85 tl=left_search(x,n,1); 86 printf("%d %d\n",tl-1,tr-1); 87 update(1,1,n,tl,tr,1); 88 } 89 } 90 printf("\n"); 91 } 92 return 0; 93 }
展开可以写成只用query和update函数:
1 #include2 #include<string.h> 3 #include 4 using namespace std; 5 int n,ll; 6 int setv[200005],sumv[200005]; 7 int query(int o,int l,int r,int y1,int y2) 8 { 9 if (setv[o]>=0) return setv[o]*(min(r,y2)-max(l,y1)+1); 10 else if (y1<=l&&y2>=r) return sumv[o]; 11 else{ 12 int mid=l+(r-l)/2,tmp=0; 13 if (y1<=mid) tmp+=query(o*2,l,mid,y1,y2); 14 if (y2>mid) tmp+=query(o*2+1,mid+1,r,y1,y2); 15 return tmp; 16 } 17 } 18 void update(int o,int l,int r,int y1,int y2,int v) 19 { 20 int mid=l+(r-l)/2; 21 if (y1<=l&&y2>=r) setv[o]=v; 22 else{ 23 if (setv[o]>=0){ 24 setv[o*2]=setv[o*2+1]=setv[o]; 25 setv[o]=-1; 26 } 27 if (y1<=mid) update(o*2,l,mid,y1,y2,v); 28 else if (setv[o*2]>=0) sumv[o*2]=setv[o*2]*(mid-l+1); 29 if (y2>mid) update(o*2+1,mid+1,r,y1,y2,v); 30 else if (setv[o*2+1]>=0) sumv[o*2+1]=setv[o*2+1]*(r-mid); 31 } 32 if (setv[o]>=0) sumv[o]=setv[o]*(r-l+1); 33 else sumv[o]=sumv[o*2]+sumv[o*2+1]; 34 } 35 int left_search(int l,int r,int num) 36 { 37 int mid=l+(r-l)/2; 38 if (l==r) return l; 39 int tmp=query(1,1,n,ll,mid); 40 if (tmp+num<=mid-ll+1) return left_search(l,mid,num); 41 return left_search(mid+1,r,num); 42 } 43 int right_search(int l,int r) 44 { 45 int mid=l+(r-l)/2+1; 46 if (l==r) return l; 47 int tmp=query(1,1,n,mid,n); 48 if (tmp+1<=n-mid+1) return right_search(mid,r); 49 return right_search(l,mid-1); 50 } 51 int main() 52 { 53 int T,m,k,x,y,tmp,tl,tr; 54 scanf("%d",&T); 55 while (T--) 56 { 57 scanf("%d%d",&n,&m); 58 memset(sumv,0,sizeof(sumv)); 59 memset(setv,-1,sizeof(setv)); 60 while (m--) 61 { 62 scanf("%d%d%d",&k,&x,&y); 63 if (k==2) 64 { 65 x++; y++; 66 tmp=query(1,1,n,x,y); 67 printf("%d\n",tmp); 68 update(1,1,n,x,y,0); 69 } 70 else{ 71 x++; 72 tmp=query(1,1,n,x,n); 73 if (tmp==n-x+1) { 74 printf("Can not put any one.\n"); 75 continue; 76 } 77 ll=x; 78 if (n-x+1-tmp right_search(x,n); 79 else tr=left_search(x,n,y); 80 tl=left_search(x,n,1); 81 printf("%d %d\n",tl-1,tr-1); 82 update(1,1,n,tl,tr,1); 83 } 84 } 85 printf("\n"); 86 } 87 return 0; 88 }
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4614