近期發現這篇題解有點爛,更新一下,刪繁就簡,詳細重點。**多加了注釋。就醬紫啦!
我們需要先算美妙度的字首和,並初始化rmq。迴圈 \(i\) 從 \(1\) 到 \(n\) ,因為以i為起點的和弦終點必定是 \(i + l - 1\) 到 \(i + r - 1\) 之間,所以只要在區間內用rmq取超級和弦,並加入以美妙度從小排到大的優先佇列中。
取出堆頂元素,將美妙度加入 \(ans\) ,並將元素切為從 (當前元素的左邊界 到 當前元素終點 - 1) 和 (\(當前元素終點 + 1 到 當前元素右邊界\)) 兩個部分,並再次加入優先佇列,依次進行 \(k\) 次。
輸出答案即可
為什麼要使用字首和 and rmq?資料範圍是500000,很明顯,為了優化需要字首和 and rmq。
字首和最明顯的用處,是可以優化乙個用來迴圈累加和的 \(n\) 。而 \(rmq\) ,顯然區間最值符合題目要求。
這兩個演算法詢問答案都是o(1)。字首和後面減去前面,rmq只需要初始化一下,然後o(1)詢問即可。
為什麼第三步要切開元素並放入優先佇列? 直接累加前 \(k\) 個元素不行麼?首先,我們肯定可以確定:優先佇列中第一大的和弦一定是 \(全域性\) 最大的和弦。 不要問我怎麼證明
那麼優先佇列中第二大的和弦一定是 \(全域性\) 次大的和弦麼?這就不一定了。
所以我們需要切開元素並放入優先佇列,保證每次取出來的元素一定是全域性大小排名的元素
自己拿出紙和筆,結合題解自己思考,在草稿紙上演算一下,就懂了
實在還有問題,私信本人233
#include#include#pragma gcc optimize(2)
#define in(a) a = read()
#define out(a) write(a)
#define outn(a) out(a),putchar('\n')
#define ll long long
#define min(a,b) a < b ? a : b
#define max(a,b) a > b ? a : b
#define rg register
#define new ll
using namespace std;
namespace io_optimization
while(isdigit(ch))
return w ? -x : x;
} inline void write(new x)
#undef new
}using namespace io_optimization;//上面一坨優化的東西不用在意
const int maxn = 500000 + 2;//定義常亮
int n,k,l,r;
int sum[maxn],lg[maxn],dp[maxn][20],pos[maxn][20];
// 字首和 lg2值
//dp[i][j]表示i的2^j次方祖先 pos陣列來記錄最佳位置
ll ans;
struct node };
inline void rmq_init() //預處理
else
}return;
} inline int rmq_query(int l, int r) //返回最值的位置
int main()
rmq_init();//初始化
priority_queuepq; //定義優先佇列
for(rg int i = 1;i + l - 1 <= n; ++i) //計算每個位置最大的超級和弦
for(rg int i = 1;i <= k; ++i) //取k次堆頂的值
if(cur.t < cur.right) //當前取最值的位置 小於 當前和弦的 右邊界
}outn(ans);
return 0;
}
洛谷 P2048 NOI2010 超級鋼琴
給出乙個序列,求和最大的k個連續子串行的和,且連續子串行長度在l與r之間.首先預處理出字首和,我們可以從左端點開始考慮,若左端點為i,則右端點在i l 1與i r 1之間,那麼可以計算出這些區間的最大值,然後放到堆裡去,每次從堆中取出最大值加到ans中後再將該區間左右兩區間的最大值放入堆中.也就是說...
P2048 NOI2010 超級鋼琴
小z是乙個小有名氣的鋼琴家,最近c博士送給了小z一架超級鋼琴,小z希望能夠用這架鋼琴創作出世界上最美妙的 這架超級鋼琴可以彈奏出n個音符,編號為1至n。第i個音符的美妙度為ai,其中ai可正可負。乙個 超級和弦 由若干個編號連續的音符組成,包含的音符個數不少於l且不多於r。我們定義超級和弦的美妙度為...
P2048 NOI2010 超級鋼琴
和十二省聯考d1t2相似的思路 用堆維護最大值,取出乙個位置之後把這個位置的下乙個值插入堆 注意插入的數有負數,並且開long long include include include include define int long long using namespace std struct q...