日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

kb-07线段树-12--二分查找区间边界

發布時間:2025/5/22 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 kb-07线段树-12--二分查找区间边界 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1 /* 2 hdu4614 3 本題剛開始想能不能記錄該區間最前面開始的點,最后面的點,區間空的數量;但是病不行 4 然后線段樹的本質是區間操作,所以!這題主要就是區間的空的全放滿,只要定出區間的邊界就好辦了; 5 這里用二分查找的方法,現計算滿足數量的區間的尾,因為頭已經確定了,及時不放花也是確定的,只要靠數量定出尾就可以了; 6 然后就是區間修改了; 7 */ 8 #include<iostream> 9 #include<cstdio> 10 #include<cstring> 11 #include<algorithm> 12 #define MAX_N 50001 13 using namespace std; 14 int n,m,first,last,num,x; 15 struct tree 16 { 17 int l,r,fir,las,s,same,val; 18 }tr[MAX_N*4]; 19 void build(int rt,int l,int r) 20 { 21 tr[rt].l=l;tr[rt].r=r; 22 tr[rt].fir=l; 23 tr[rt].las=r; 24 tr[rt].s=0; 25 tr[rt].val=r-l+1; 26 if(l==r) 27 { 28 tr[rt].same=0; 29 return ; 30 } 31 tr[rt].same=1; 32 int mid=(l+r)/2; 33 build(rt<<1,l,mid); 34 build(rt<<1|1,mid+1,r); 35 } 36 void Pushup(int rt) 37 { 38 int l=rt<<1,r=rt<<1|1; 39 if(tr[l].fir==0) 40 tr[rt].fir=tr[r].fir; 41 else tr[rt].fir=tr[l].fir; 42 if(tr[r].las==0) 43 tr[rt].las=tr[l].las; 44 else tr[rt].las=tr[r].las; 45 tr[rt].val=tr[r].val+tr[l].val; 46 47 } 48 void Pushdown(int rt) 49 { 50 if(tr[rt].l==tr[rt].r) 51 return ; 52 int l=rt<<1,r=rt<<1|1; 53 if(tr[rt].same) 54 { 55 if(tr[rt].s==1) 56 { 57 tr[r].val=tr[l].val=0; 58 tr[r].s=tr[l].s=1; 59 tr[r].fir=tr[l].fir=0; 60 tr[r].las=tr[l].las=0; 61 tr[r].same=tr[l].same=1; 62 tr[rt].same=0; 63 } 64 else 65 { 66 tr[r].val=tr[r].r-tr[r].l+1; 67 tr[l].val=tr[l].r-tr[l].l+1; 68 tr[r].s=tr[l].s=0; 69 tr[r].same=tr[l].same=1; 70 tr[r].fir=tr[r].l; 71 tr[r].las=tr[r].r; 72 tr[l].fir=tr[l].l; 73 tr[l].las=tr[l].r; 74 tr[rt].same=0; 75 } 76 } 77 } 78 void Update1(int rt,int l,int r) 79 { 80 if(x<=0) 81 return ; 82 if(tr[rt].val==0) 83 return ;//在二分查找定區間后,少了這一句所以一直tle 84 if(tr[rt].l==l&&tr[rt].val>0) 85 { 86 if(first==0) 87 first=tr[rt].fir; 88 if(tr[rt].val<=x) 89 { 90 if(last<tr[rt].las) 91 last=tr[rt].las; 92 x-=tr[rt].val; 93 tr[rt].same=1; 94 tr[rt].s=1; 95 tr[rt].val=0; 96 tr[rt].fir=0; 97 tr[rt].las=0; 98 return ; 99 } 100 } 101 if(tr[rt].l==tr[rt].r) 102 return ; 103 Pushdown(rt); 104 int L=rt<<1,R=rt<<1|1; 105 if(l<=tr[L].r) 106 { 107 if(r<=tr[L].r) 108 Update1(L,l,r); 109 else 110 Update1(L,l,tr[L].r); 111 } 112 if(r>=tr[R].l) 113 { 114 if(l>=tr[R].l) 115 Update1(R,l,r); 116 else 117 Update1(R,tr[R].l,r); 118 } 119 Pushup(rt); 120 } 121 void Update2(int rt,int l,int r) 122 { 123 if(tr[rt].l==l&&tr[rt].r==r) 124 { 125 num+=r-l+1-tr[rt].val; 126 tr[rt].val=r-l+1; 127 tr[rt].s=0; 128 tr[rt].same=1; 129 tr[rt].fir=l; 130 tr[rt].las=r; 131 return; 132 } 133 if(tr[rt].l==tr[rt].r) 134 return ; 135 Pushdown(rt); 136 int L=rt<<1,R=rt<<1|1; 137 if(l<=tr[L].r) 138 { 139 if(r<=tr[L].r) 140 Update2(L,l,r); 141 else 142 Update2(L,l,tr[L].r); 143 } 144 if(r>=tr[R].l) 145 { 146 if(l>=tr[R].l) 147 Update2(R,l,r); 148 else 149 Update2(R,tr[R].l,r); 150 } 151 Pushup(rt); 152 } 153 int sum(int rt,int l,int r) 154 { 155 if(tr[rt].l==l&&tr[rt].r==r) 156 { 157 return tr[rt].val; 158 } 159 int ans=0; 160 Pushdown(rt);//因為只是查詢,所以區間整體并沒有變,就沒有必要pushup了; 161 int L=rt<<1,R=rt<<1|1; 162 if(l<=tr[L].r) 163 { 164 if(r<=tr[L].r) 165 ans+= sum(L,l,r); 166 else 167 ans+= sum(L,l,tr[L].r); 168 } 169 if(r>=tr[R].l) 170 { 171 if(l>=tr[R].l) 172 ans+= sum(R,l,r); 173 else 174 ans+= sum(R,tr[R].l,r); 175 } 176 return ans; 177 } 178 int bisearch(int a,int f) 179 { 180 if(sum(1,a,n)==0) 181 return -1; 182 if(sum(1,a,n)<f)//此處的等于號的問題; 183 return n; 184 int l=a,r=n; 185 int ans=a; 186 while(l<=r) 187 { 188 int mid=(l+r)/2; 189 if(sum(1,a,mid)>=f)//以及此處的等于號; 190 { 191 ans=mid;//這里ans的取值; 192 r=mid-1; 193 } 194 else l=mid+1; 195 } 196 return ans; 197 } 198 int main() 199 { 200 int T; 201 scanf("%d",&T); 202 while(T--) 203 { 204 scanf("%d%d",&n,&m); 205 build(1,1,n); 206 for(int i=0;i<m;i++) 207 { 208 int ty,z,y; 209 scanf("%d%d%d",&ty,&z,&y); 210 if(ty==1) 211 { 212 int t=bisearch(z+1,y); 213 if(t!=-1) 214 { 215 x=y; 216 first=0; 217 last=0; 218 Update1(1,z+1,t); 219 printf("%d %d\n",first-1,last-1); 220 } 221 else 222 printf("Can not put any one.\n"); 223 } 224 else 225 { 226 num=0; 227 Update2(1,z+1,y+1); 228 printf("%d\n",num); 229 } 230 } 231 printf("\n"); 232 } 233 return 0; 234 }

?

轉載于:https://www.cnblogs.com/by-1075324834/p/4543002.html

總結

以上是生活随笔為你收集整理的kb-07线段树-12--二分查找区间边界的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。