BZOJ2006 [NOI2010]超級鋼琴 【堆 + RMQ】

2006: [NOI2010]超級鋼琴

Time Limit:?20 Sec??Memory Limit:?552 MB
Submit:?3446??Solved:?1692
[Submit][Status][Discuss]

Description

小Z是一個小有名氣的鋼琴家,最近C博士送給了小Z一架超級鋼琴,小Z希望能夠用這架鋼琴創作出世界上最美妙的
音樂。 這架超級鋼琴可以彈奏出n個音符,編號為1至n。第i個音符的美妙度為Ai,其中Ai可正可負。 一個“超級
和弦”由若干個編號連續的音符組成,包含的音符個數不少于L且不多于R。我們定義超級和弦的美妙度為其包含的
所有音符的美妙度之和。兩個超級和弦被認為是相同的,當且僅當這兩個超級和弦所包含的音符集合是相同的。?
小Z決定創作一首由k個超級和弦組成的樂曲,為了使得樂曲更加動聽,小Z要求該樂曲由k個不同的超級和弦組成。
我們定義一首樂曲的美妙度為其所包含的所有超級和弦的美妙度之和。小Z想知道他能夠創作出來的樂曲美妙度最
大值是多少。

Input

第一行包含四個正整數n, k, L, R。其中n為音符的個數,k為樂曲所包含的超級和弦個數,L和R分別是超級和弦所
包含音符個數的下限和上限。 接下來n行,每行包含一個整數Ai,表示按編號從小到大每個音符的美妙度。
N<=500,000
k<=500,000
-1000<=Ai<=1000,1<=L<=R<=N且保證一定存在滿足條件的樂曲

Output

只有一個整數,表示樂曲美妙度的最大值。

Sample Input

4 3 2 3
3
2
-6
8

Sample Output

11

【樣例說明】
共有5種不同的超級和弦:
音符1 ~ 2,美妙度為3 + 2 = 5
音符2 ~ 3,美妙度為2 + (-6) = -4
音符3 ~ 4,美妙度為(-6) + 8 = 2
音符1 ~ 3,美妙度為3 + 2 + (-6) = -1
音符2 ~ 4,美妙度為2 + (-6) + 8 = 4
最優方案為:樂曲由和弦1,和弦3,和弦5組成,美妙度為5 + 2 + 4 = 11。


我們利用前綴和可以很快得到最大的答案

對于每個點i,我們只要求出sum[i + L - 1] 到 sum[i + R - 1]中最大的值就可以得到以i為左端點的最大值

我們設這樣一個值為三元組(i,l,r)的值,表示以i開頭右端點在[l,r]內的區間最大和

利用這個,我們求出最大值后,求第二大的值可能以其它i開頭,也可能仍然以當前i開頭,我們就把當前(i,l,r)分裂成

(i,l,t - 1)和(i,t + 1,r)就可以了

重復K次,即得結果


但是如何做到快速求區間最大值呢?

這就用到了RMQ算法【ST表】

ST表是用以解決區間最大值無修改的算法,預處理O(nlogn),查詢O(1)

可以說在沒有修改的情況下比線段樹優很多


具體實現:

預處理

我們設mx[i][j]表示以[i,i + 2^j - 1],也就是以i開頭長度為2^j的區間的最大值

利用倍增的方法,mx[i][j] = max(mx[i][j - 1],mx[i + 2^(j - 1)][j - 1]);

我們可以處理出所有的mx【但是要注意數組不要越界】


查詢

我們要查詢的區間長度是2的n次方很好辦,就是mx[i][n]
但是如果不是呢?
我們可以把原區間分成兩個相交的2^n的區間,求二者的最大值即可
具體區間為[l,r],我們令t = log2(r - l + 1),則ans = max(mx[l][t],mx[r - 2^t?+ 1][t]);

最后我們就可以A啦
【STL似乎不會T】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#define mp(a,b,c,d) (node){a,b,c,d}
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
using namespace std;
const int maxn = 500005,maxm = 100005,INF = 1000000000;
inline int RD(){int out = 0,flag = 1; char c = getchar();while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}return out * flag;
}
int N,K,L,R,sum[maxn],mx[maxn][30],Log[maxn];
LL ans = 0;
struct node{int i,l,r,t;};
inline bool operator <(const node& a,const node& b){return sum[a.t] - sum[a.i - 1] < sum[b.t] - sum[b.i - 1];}
priority_queue<node,vector<node> > q;
void RMQ(){Log[0] = -1;for (int i = 1; i <= N; i++) Log[i] = Log[i >> 1] + 1;int t = Log[N];REP(i,N) mx[i][0] = i;for (int i = N; i; i--){for (int j = 1; j <= t; j++){if (i + (1 << j) - 1 > N) break;int t1 = mx[i][j - 1],t2 = mx[i + (1 << j - 1)][j - 1];mx[i][j] = sum[t1] > sum[t2] ? t1 : t2;}}
}
inline int Query(int l,int r){if (l == r) return l;int t = Log[r - l + 1],t1 = mx[l][t],t2 = mx[r - (1 << t) + 1][t];return sum[t1] > sum[t2] ? t1 : t2;
}
void solve(){node u;REP(i,N){if (i + L - 1 > N) break;int r = min(i + R - 1,N);q.push(mp(i,i + L - 1,r,Query(i + L - 1,r)));}for (int i = 1; i <= K; i++){u = q.top(); q.pop();ans += sum[u.t] - sum[u.i - 1];if (u.t - 1 >= u.l) q.push(mp(u.i,u.l,u.t - 1,Query(u.l,u.t - 1)));if (u.t + 1 <= u.r) q.push(mp(u.i,u.t + 1,u.r,Query(u.t + 1,u.r)));}
}
int main(){N = RD(); K = RD(); L = RD(); R = RD();REP(i,N) sum[i] = sum[i - 1] + RD();RMQ();solve();cout<<ans<<endl;return 0;
}


轉載于:https://www.cnblogs.com/Mychael/p/8282785.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/251388.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/251388.shtml
英文地址,請注明出處:http://en.pswp.cn/news/251388.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue項目代碼改進(六)—— vue的mixins的使用

混入可以將不同組件的共同內容部分在一個混入對象中展示&#xff0c;然后通過在組件實例中混入這個對象&#xff0c;這樣擁有這些屬性的組件都可以調用 混入對象中的屬性名跟組件中的屬性名沖突時&#xff0c;以組件自身的為基準 舉例&#xff1a;單文件組件users.vue 1&#x…

es6 --- Promise.catch

Promise.prototype.catch(): 是.then(null, rejection)的別名,用于指定發生錯誤時的回調函數 p.then( (val) -> console.log(fulfilled:, val)).catch( (err) > console.log(rejected, err));// 等同于 p.then( (val) > console.log(fulfilled:, val)).then(null, (e…

爬蟲的一些工具(二)

爬蟲的一些工具(二) 1. 常有的工具 (1). python(2). pycharm(3).瀏覽器i.chromeii.火狐(4).fiddler的使用2 fiddler的使用 (1).操作界面(2)界面含義請求(Request)部分詳解名稱含義Headers顯示客戶端發送到服務器的 HTTP 請求的,header 顯示為一個分級視圖&#xff0c;包含了 We…

微信開發者工具一打開代碼編輯區文件全部不見了

今天開微信開發者工具時&#xff0c;一打開竟然文件全部不見了&#xff01;然后頁面也編譯不出來&#xff0c;搜了一下大神們的建議&#xff1a; 1、在編輯器控制臺輸入&#xff1a;openVendor 回車 會打開一個文件夾&#xff1a;C:\Users\Administrator\AppData\Local\微信we…

vue項目中所使用的element-UI / echarts

高清版思維導圖見后臺管理項目地址 1.login登錄頁面 < el-form >表單 在 Form 組件中&#xff0c;每一個表單域由一個 Form-Item 組件構成&#xff0c;表單域中可以放置各種類型的表單控件&#xff0c;包括 Input、Select、Checkbox、Radio、Switch、DatePicker、TimeP…

es6 --- 使用yield*命令遍歷完全二叉樹

首先定義二叉樹的結構: // 定義二叉樹的結構 function Tree(left, label, right) {this.left left;this.label label;this.right right; }// 對二叉樹采用中序遍歷 function* inorder(t) {if(t) {yield* inorder(t.left);yield t.label;yield* inorder(t.right);} }// 生成…

面向對象之繼承與派生

閱讀目錄 一 初識繼承二 繼承與抽象&#xff08;先抽象再繼承&#xff09;三 繼承與重用性四 派生五 組合與重用性六 接口與歸一化設計七 抽象類八 繼承實現的原理&#xff08;可惡的菱形問題&#xff09;九 子類中調用父類的方法一 初識繼承 什么是繼承 繼承是一種創建新類的方…

SpringBoot(十三)-- 不同環境下讀取不同配置

一、場景&#xff1a; 在開發過程中 會使用 開發的一套數據庫&#xff0c;測試的時候 又會使用測試的數據庫&#xff0c;生產環境中 又會切換到生產環境中。常用的方式是 注釋掉一些配置&#xff0c;然后釋放一下配置。SpringBoot提供了在不同環境下切換不同配置的功能&#xf…

MDN文檔基礎知識搜集

Array數組&#xff0c;一種允許你存儲多個值在一個引用里的結構。var myVariable [1,Bob,Steve,10]; 引用數組的元素只需&#xff1a;myVariable[0], myVariable[1], 等等. 發布工具: FTP 客戶端 你還需要一種將文件從本地硬盤上傳到遠程Web服務器的方法。 為了做到這一點&am…

vue-cli生成項目時你應當知道的

一、安裝 npm install -g vue-cli二、創建項目 vue init 模板名 項目名 vue init webpack mymall模板名: 1 . webpack 最常用 2 . webpack-simple // 一個簡單webpackvue-loader的模板&#xff0c;不包含其他功能。 3 . browserify // 一個全面的Browserifyvueify 的模板&am…

es6 --- 正確獲取Generator函數內部的this對象使其可以使用new

首先看2個例子 function * g() {this.a 11; }let o g(); console.log(o.a);可以看見Generator函數里面的this指向的對象取不出來. 再看下一個例子: function* F() {yield this.x 2;yield this.y 3; } new F();可以看出Generator函數無法使用new操作符, 下面一共一個解決…

mysql三-3:完整性約束

閱讀目錄 一 介紹二 not null與default三 unique四 primary key五 auto_increment六 foreign key七 作業一 介紹 約束條件與數據類型的寬度一樣&#xff0c;都是可選參數 作用&#xff1a;用于保證數據的完整性和一致性主要分為&#xff1a; PRIMARY KEY (PK) 標識該字段為該…

LOL

[分享] 從《LOL》談游戲中的隨機動作優化 http://bbs.gameres.com/thread_472292.html 光子工作室陳宇復盤《全民突擊》研發歷程&#xff08;完整版&#xff09; https://mp.weixin.qq.com/s?__bizMjM5OTc2ODUxMw&mid400110877&idx2&sn372fd6492a9d8dd1791d87eb2c…

超級簡易法上傳本地文件到github上

之前文章寫過廖雪峰老師關于git教程的帖子&#xff0c;現在終于有時間實踐了&#xff01;我這段時間在學微信小程序版的貪吃蛇&#xff0c; 想著先把寫好的文件上傳試試&#xff0c;于是乎&#xff0c;便有了如下…… 大家要是不想聽廢話可以拉到最后去…… 1、我先在github…

es6 --- 對任意對象部署可遍歷接口

有時候需要對對象進行遍歷,下面提供一個比較方便的接口, 其基本思路是,首先得到對象的所有鍵(key), 然后將其放在yield* 后面. yield* 可以通過 for … of … 循環遍歷 具體實現如下: function* iterEntries (obj) {let keys Object.keys(obj);for ( let i 0; i < keys.…

element-ui表單驗證:用戶名、密碼、電話、郵箱

之前設計login組件時增加了簡單的表單驗證&#xff0c;因此對應的users組件&#xff0c;添加用戶功能也必須設置相應的驗證規則。 文檔form表單驗證只提供了用戶名/密碼&#xff0c;是否必須/長度限制的驗證。對于電話、郵箱和地址的驗證如下&#xff1a; html部分&#xff0c…

composer(作曲家)安裝php-ml

剛開始我用的是up5.6版本php命令安裝composer 后來使用composer時發現命令行會提示php版本太低 于是我下載了wamp&#xff0c;使用7.1版本的php重新安裝了composer&#xff0c;因為php-ml要求必須是7.1版本 在安裝的時候有一些問題&#xff0c;那就是安裝不成功&#xff0c;并沒…

前端解析返回的對象時json顯示$ref問題的解決

在mapper中寫的語句&#xff0c;結果集中association&#xff0c;采用的一個對象&#xff0c;整個list列表中每個元素有一個對象元素&#xff0c;如果第二個元素中有一個與第一個元素中對象同名的&#xff0c;就會去引用上一個元素的地址&#xff0c;在json前臺解析的時候就不會…

Uncaught TypeError: Cannot redefine property: $router

原因&#xff1a;就如報錯提示所描述的&#xff0c;不能重新定義router&#xff0c;說明是重復定了router&#xff0c;說明是重復定了router&#xff0c;說明是重復定了router。通常是因為在項目中安裝了vue-router的依賴并且用Vue.use()使用了vue-router&#xff0c;還在index…

微信小程序模仿開眼視頻app(一)——視頻首頁、視頻詳情、分類

可到我的github賬號上去copy文件 先展示一下我實現了的功能吧 提示&#xff0c;如果有出現無法加載域名之類問題的的&#xff0c;可以在“設置”-“項目設置”-打鉤“不校驗合法域名……”&#xff1b; 或者直接登錄自己的微信小程序后臺設置域名信息 首頁部分&#xff1a; 1…