POJ2104 K-th Number 靜態區間第k最值 平方分割

来源:http://www.cnblogs.com/Onlynagesha/archive/2016/04/05/5353531.html
-Advertisement-
Play Games

幹掉這道題的那一刻,我只想說:我終於**的AC了!!! 最終記憶體1344K,耗時10282ms,比起歸併樹、劃分樹以及其他各種黑科技,這個成績並不算光彩⊙﹏⊙ 但至少,從最初的無數次TLE到最終的AC,這過程見證了一個二分演算法的艱辛優化 先貼代碼: 1 const int bktSize=1024; ...


幹掉這道題的那一刻,我只想說:我終於**的AC了!!!

最終記憶體1344K,耗時10282ms,比起歸併樹、劃分樹以及其他各種黑科技,這個成績並不算光彩⊙﹏⊙

但至少,從最初的無數次TLE到最終的AC,這過程見證了一個二分演算法的艱辛優化

先貼代碼:

 1 const int bktSize=1024;
 2 const int bktMaxIdx=bktSize-1;
 3 const int bktCount=128;
 4 const int bktDigit=10;
 5 const int maxV=1e9;
 6 
 7 int bucket[bktCount][bktSize];
 8 int unOrdered[bktSize*bktCount];
 9 int ordered[bktSize*bktCount];
10 int N,K;
11 
12 #include <cstdio>
13 #include <cstring>
14 #include <algorithm>
15 
16 void init()
17 {
18     scanf("%d%d",&N,&K);
19     memset(bucket[N>>bktDigit],0x7f,sizeof(bucket[N>>bktDigit]));
20     for(int i=0;i<N;i++) 
21     {
22         scanf("%d",unOrdered+i);
23         ordered[i]=unOrdered[i];
24         bucket[i>>bktDigit][i&bktMaxIdx]=unOrdered[i];
25     }
26     
27     using std::sort;
28     int bktUsed=N>>bktDigit;
29     sort(ordered,ordered+N);
30     for(int i=0;i<=bktUsed;i++) sort(bucket[i],bucket[i]+bktSize);
31 }
32 
33 inline void enumerate(int _rangeL,int _rangeR,int _val,int& _notMore)
34 {
35     for(int i=_rangeL;i<=_rangeR;i++)
36         if(unOrdered[i]<=_val) ++_notMore;
37 }
38 
39 inline void countBucket(int _bktIdx,int _val,int& _notMore)
40 {
41     using std::upper_bound;
42     
43     int* ub=upper_bound(bucket[_bktIdx],bucket[_bktIdx]+bktSize,_val);
44     _notMore+=(ub-bucket[_bktIdx]);
45 }
46 
47 int ask(int _rangeL,int _rangeR,int _k) //k-th smallest
48 {
49     int digitL=_rangeL>>bktDigit;
50     int digitR=_rangeR>>bktDigit;
51     int vL=0;
52     int vR=N-1;
53     
54     while(vL<vR)
55     {
56         int midV=(vL+vR)>>1;
57         int notMore=0;
58         if(digitL==digitR) 
59             enumerate(_rangeL,_rangeR,ordered[midV],notMore);
60         else
61         {
62             for(int i=digitL+1;i<digitR;i++)
63                 countBucket(i,ordered[midV],notMore);
64             enumerate(_rangeL,((digitL+1)<<bktDigit)-1,ordered[midV],notMore);
65             enumerate(digitR<<bktDigit,_rangeR,ordered[midV],notMore);
66         }
67         
68         if(notMore<_k) vL=midV+1;
69         else vR=midV;
70     }
71     return ordered[vL];
72 }
73 
74 int main()
75 {
76     init();
77     for(int i=0;i<K;i++)
78     {
79         int l,r,k;
80         scanf("%d%d%d",&l,&r,&k);
81         printf("%d\n",ask(l-1,r-1,k));    
82     }
83     return 0;
84 }
View Code

 

1、為什麼統計notMore,而不是統計less或者兩者都統計?

二分的過程中,縮減區間的關鍵是:

1、必須使可能成為最終解的值保留在二分區間中

2、每一次都必須使區間大小的確被縮減,以防陷入死迴圈

在這道題中,某個值x為解的條件是:less(x)<x && notMore(x)>=x

如果統計Less的話,上面的代碼很難是保證第一條的

而如果兩者都統計的話,錶面上當x滿足條件時即可跳出,可以減少二分所需的時間

但是事實上,這樣做的代價就是統計的時間複雜度常數乘以2,總的來說得不償失(會TLE)

2、二分的對象是什麼?可否把maxValue和minValue作為二分的對象?

Answer:NO!!!

正確的做法是將原數組排好序,然後對這個有序數組二分

理由很簡單:範圍小。二分區間長不會超過1e5

如果對數值本身二分的話,minValue和maxValue最壞時分別會達到-1e9和+1e9,二分的時間代價是前者的1.9倍

3、平方分割必須是嚴格的麽?

Answer:NO(*^__^*)

設數據規模為N,每個桶的大小為B,則單次詢問的時間複雜度為: O ( (N / B ) * log B + B )

當B = O ( ( N * log N ) ^ 0.5 ) 時,總的時間複雜度會比嚴格的平方分割小一些

代碼中將B取為了1024正是為此。(順便也方便了位運算)

B取512時效率會相對變差,B取256時乾脆TLE

 

這道題更好的做法是歸併樹,比歸併樹還好的做法是劃分樹,不過這都是後話了,有時間慢慢填坑


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在Linux中,主要編輯器為vi或者vim,本文圍繞vim做簡單的講解說明: Linux預設自帶vi(vim)編輯器,其程式包為: vim 編輯器模式切換: 命令模式 、命令行模式、編輯模式 命令模式: 字元操作 i 當前字元之前插入 I 行首插入 a 當前字元之後插入 A 行尾插入 esc 退出當 ...
  • PHP的語言規範: 1、php中的變數名區分大小寫,但是函數名,類名,方法名,不區分大小寫,但建議區分大小寫 2、php代碼必須書寫在(php標簽),開啟標記(<?php)中間不能空格 3、php代碼每一行以分號結束,最後一行可以省略分號。 4、如果一個Php文件是由純 php代碼組成,那麼php結... ...
  • i = 0def myFun(): global i i=i +1 return i myFun() accumulate( ) total = 0def accumulate(): global total total += 1 return total ...
  • oauth應該屬於security的一部分。關於oauth的的相關知識可以查看阮一峰的文章:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html 一、目標 現在很多系統都支持第三方賬號密碼等登陸我們自己的系統,例如:我們經常會看到,一些系統使用微 ...
  • 最近遇到的問題小結: 1.django 工程內不要有與項目名稱相同的文件。會導致無法import settings.py文件。 2.django 的 csrf 問題,當發送post請求時,會要求同時發送csrf token,是為了防止跨站請求偽造。 具體使用方法見官方文檔。 http://docs. ...
  • 介紹 我發現了一個問題,今天與大家分享。我把整個過程描述一下。 問題 問題 公司有個框架是基於smarty寫的,我負責php的升級,維護人員把新環境布上來之後,測試人員找我提出經常報錯(錯誤:提示找不到文件的)。 我追蹤了一下代碼,原來是smarty的這個地方報的錯誤。 錯誤:這裡報出文件不存在。 ...
  • 開篇導讀 “養成良好的編程習慣”其實是相當綜合的一個命題,可以從多個角度、維度和層次進行論述和評判。如代碼的風格、效率和可讀性;模塊設計的靈活性、可擴展性和耦合度等等。要試圖把所有方面都闡述清楚必須花很多的精力,而且也不一定能闡述得全面。因此,本系列文章以軟體開發的基礎問題為切入點,闡述程式設計和代 ...
  • 初始化一個map 1 2 3 4 5 Map<String, String> map = new HashMap<String, String>(); map.put("1", "hell"); map.put("2", "hello"); map.put("3", "hel"); map.put( ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...