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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ2104 (平方分割)二分查找理解。

發(fā)布時間:2023/11/30 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ2104 (平方分割)二分查找理解。 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題意:任意區(qū)間求第k大數(shù)

思路:

  預(yù)處理:利用平方分割(分桶法)把區(qū)間切割成B = sqrt(n)大小的一塊塊,然后每個各自排序。

  二分第k大數(shù)x,接著就需要求[l,r]區(qū)間中x的排名,與k比較,將兩邊端點非完整桶的點進(jìn)行掃描,最多B次,其余每個桶進(jìn)行二分查找排名,可利用upper_bound(STL)即可快速實現(xiàn)。

評價:

  二分確實坑爹,不過搞了這一題也算對二分查找理解深入了些。

二分正確做法:

對于[0..n-1)有[0..m]滿足性質(zhì)其余不滿足, 則應(yīng)用[l, r)進(jìn)行二分查找, 最后l一定是正確的。總是保證l不成立,r成立。

l = -1, r = n; while(l < r-1) {int mid = (l+r)/2;if(check(mid))l = mid;elser = mid; } cout << l << endl;

而若是[m, n-1]滿足性質(zhì), 則應(yīng)用(l, r]進(jìn)行二分查找, 最后r一定正確,反之即可。

?

保證(l, r]正確性

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cstdlib> #include <cmath> #include <utility> #include <vector> #include <queue> #include <map> #include <set> #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)>(y)?(y):(x)) #define INF 0x3f3f3f3f #define MAXN 200005 #define B 1000using namespace std;vector<int> bucket[MAXN/B]; int a[MAXN], q[MAXN], n, m, x, y, k;int main() {scanf("%d%d", &n, &m);for(int i = 0; i < n; i ++){scanf("%d", &a[i]);q[i] = a[i];bucket[i/B].push_back(a[i]);}sort(q, q+n);for(int i = 0; i < MAXN/B; i ++)sort(bucket[i].begin(), bucket[i].end());while(m --){scanf("%d%d%d", &x, &y, &k);x--, y;int l = -1, r = n-1; //(l, r]while(l < r-1){int mid = (l+r)/2;int tx = x, ty = y;int cnt = 0;for( ; tx < ty && tx%B != 0; tx ++)if(a[tx] <= q[mid]) cnt ++;for( ; tx < ty && ty%B != 0; ty --)if(a[ty-1] <= q[mid]) cnt ++;for(int i = tx/B; i < ty/B; i ++)cnt += upper_bound(bucket[i].begin(), bucket[i].end(), q[mid])-bucket[i].begin();if(k <= cnt)r = mid;elsel = mid;}if(r < 0)printf("-1");elseprintf("%d\n", q[r]);}return 0; } View Code

?

例如本題若換成[l, r)正確性,稍加改動即可。

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cstdlib> #include <cmath> #include <utility> #include <vector> #include <queue> #include <map> #include <set> #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)>(y)?(y):(x)) #define INF 0x3f3f3f3f #define MAXN 200005 #define B 1000using namespace std;vector<int> bucket[MAXN/B]; int a[MAXN], q[MAXN], n, m, x, y, k;int main() {scanf("%d%d", &n, &m);for(int i = 0; i < n; i ++){scanf("%d", &a[i]);q[i] = a[i];bucket[i/B].push_back(a[i]);}sort(q, q+n);for(int i = 0; i < MAXN/B; i ++)sort(bucket[i].begin(), bucket[i].end());while(m --){scanf("%d%d%d", &x, &y, &k);x--, y;int l = 0, r = n; //[l, r)while(l < r-1){int mid = (l+r)/2;int tx = x, ty = y;int cnt = 0;for( ; tx < ty && tx%B != 0; tx ++)if(a[tx] < q[mid]) cnt ++;for( ; tx < ty && ty%B != 0; ty --)if(a[ty-1] < q[mid]) cnt ++;for(int i = tx/B; i < ty/B; i ++)cnt += lower_bound(bucket[i].begin(), bucket[i].end(), q[mid])-bucket[i].begin();if(cnt < k)l = mid;elser = mid;}printf("%d\n", q[l]);}return 0; } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/Mathics/p/4155655.html

總結(jié)

以上是生活随笔為你收集整理的POJ2104 (平方分割)二分查找理解。的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。